473,320 Members | 2,133 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,320 software developers and data experts.

Problems with memory at WTS/Citrix Servern

Hello,

currently we encounter several huge memoryproblems running .NET C#
Applications under Windows Terminal Servers/Citrix. Sometimes the program
claims 100 MB which is not very much at a single PC but a pain in the ass at
a Terminalserver when 20-25 Users start the program (25*100 = 2500 MB).

We made some analysis:

So we build a new project which only contains 2 forms. The first form just
has one button which starts the second form:

private void button1_Click(object sender, System.EventArgs e)

{

Form2 frm = new Form2();

frm.ShowDialog();

}

This second form contains a listview with 10 columns and a button in order
to fill it. After pressing the button the listview is filled:

private void button1_Click(object sender, System.EventArgs e)

{

Random rd = new Random();

Cursor.Current = Cursors.WaitCursor;

ListViewItem item;

string[] s = new string[10];

for (int i=0;i<100000;i++)

{

s[0] = rd.NextDouble().ToString();

s[1] = rd.NextDouble().ToString();

s[2] = rd.NextDouble().ToString();

s[3] = rd.NextDouble().ToString();

s[4] = rd.NextDouble().ToString();

s[5] = rd.NextDouble().ToString();

s[6] = rd.NextDouble().ToString();

s[7] = rd.NextDouble().ToString();

s[8] = rd.NextDouble().ToString();

s[9] = rd.NextDouble().ToString();

item = new ListViewItem(s);

this.lvData.Items.Add(item);

}

}

During this the memoryusage rises till 180 MB. If I close the second form
and return to the first one the memory decreases to 100 MB. This value didn't
decrease any more. So we change the code in the first form which opens the
second one:

private void button1_Click(object sender, System.EventArgs e)

{

Form2 frm = new Form2();

frm.ShowDialog();

frm.Dispose(); // NEW Statement

GC.Collect(); // NEW Statement

}

Now the memory changes after closing the second form from 100 MB to 25 MB.
This is much better but still not enough! Why does s single application with
one form and one button still uses 25 MB? At the beginning it just had 8 MB.
Run this program at a WTS by 20 Users and you have 500 MB wasted by a single
form with just one button!

We have also read the 1150 pages of ScaleNet.pdf from MSDN. I was wondering
about this sentence: AVOID CALLING GC.COLLECT. But this was the only way to
reduces the memory in my sampleapplication!

How can we solve this problem? Is there any better chance to get rid of this
waste of memory? At a normal PC it does not matter but it is critical at a
Terminal Server.

Thank you very much


Mar 2 '06 #1
3 1889
Please write a small real-world application and run this on a TS, your
conclusion based on this piece of code are not relevant. It's right, you
only have a few UI elements but you are using a lot of memory because you
are filling a listview with 100000 rows of 10 string values each. Also, the
way you fill the list is wrong, it must take ages to fill the list I guess.
Willy.
"Alexander Overmann" <ao@nospamconnex.de> wrote in message
news:44***********************@read.news.de.uu.net ...
| Hello,
|
| currently we encounter several huge memoryproblems running .NET C#
| Applications under Windows Terminal Servers/Citrix. Sometimes the program
| claims 100 MB which is not very much at a single PC but a pain in the ass
at
| a Terminalserver when 20-25 Users start the program (25*100 = 2500 MB).
|
|
|
| We made some analysis:
|
| So we build a new project which only contains 2 forms. The first form just
| has one button which starts the second form:
|
|
|
| private void button1_Click(object sender, System.EventArgs e)
|
| {
|
| Form2 frm = new Form2();
|
| frm.ShowDialog();
|
| }
|
|
|
| This second form contains a listview with 10 columns and a button in order
| to fill it. After pressing the button the listview is filled:
|
|
|
| private void button1_Click(object sender, System.EventArgs e)
|
| {
|
| Random rd = new Random();
|
| Cursor.Current = Cursors.WaitCursor;
|
| ListViewItem item;
|
| string[] s = new string[10];
|
| for (int i=0;i<100000;i++)
|
| {
|
| s[0] = rd.NextDouble().ToString();
|
| s[1] = rd.NextDouble().ToString();
|
| s[2] = rd.NextDouble().ToString();
|
| s[3] = rd.NextDouble().ToString();
|
| s[4] = rd.NextDouble().ToString();
|
| s[5] = rd.NextDouble().ToString();
|
| s[6] = rd.NextDouble().ToString();
|
| s[7] = rd.NextDouble().ToString();
|
| s[8] = rd.NextDouble().ToString();
|
| s[9] = rd.NextDouble().ToString();
|
| item = new ListViewItem(s);
|
| this.lvData.Items.Add(item);
|
| }
|
| }
|
|
|
| During this the memoryusage rises till 180 MB. If I close the second form
| and return to the first one the memory decreases to 100 MB. This value
didn't
| decrease any more. So we change the code in the first form which opens the
| second one:
|
|
|
| private void button1_Click(object sender, System.EventArgs e)
|
| {
|
| Form2 frm = new Form2();
|
| frm.ShowDialog();
|
| frm.Dispose(); // NEW Statement
|
| GC.Collect(); // NEW Statement
|
| }
|
|
|
| Now the memory changes after closing the second form from 100 MB to 25 MB.
| This is much better but still not enough! Why does s single application
with
| one form and one button still uses 25 MB? At the beginning it just had 8
MB.
| Run this program at a WTS by 20 Users and you have 500 MB wasted by a
single
| form with just one button!
|
|
|
| We have also read the 1150 pages of ScaleNet.pdf from MSDN. I was
wondering
| about this sentence: AVOID CALLING GC.COLLECT. But this was the only way
to
| reduces the memory in my sampleapplication!
|
|
|
| How can we solve this problem? Is there any better chance to get rid of
this
| waste of memory? At a normal PC it does not matter but it is critical at a
| Terminal Server.
|
|
|
| Thank you very much
|
|
|
|
Mar 2 '06 #2
Dear Willy,
sure the listview costs a lot of memory but this is at form2. If I close
form2 and return to form1 the memory does not get become free completely.

But maybe my "wrong way" of filling the listview is the reason? Tell me how
you would fill it please and I post the results of ths.
Thanx
Alex

btw: Our real-world application currently uses 60MB-150MB for each(!) user
and we also used all those "hints" found in the web:
stringbuilder, do not use boxing/unboxing to often, set ref-types to null,
GC.COLLECT etc.
Thankx

"Willy Denoyette [MVP]" <wi*************@telenet.be> schrieb im Newsbeitrag
news:O2**************@TK2MSFTNGP12.phx.gbl...
Please write a small real-world application and run this on a TS, your
conclusion based on this piece of code are not relevant. It's right, you
only have a few UI elements but you are using a lot of memory because you
are filling a listview with 100000 rows of 10 string values each. Also,
the
way you fill the list is wrong, it must take ages to fill the list I
guess.
Willy.
"Alexander Overmann" <ao@nospamconnex.de> wrote in message
news:44***********************@read.news.de.uu.net ...
| Hello,
|
| currently we encounter several huge memoryproblems running .NET C#
| Applications under Windows Terminal Servers/Citrix. Sometimes the
program
| claims 100 MB which is not very much at a single PC but a pain in the
ass
at
| a Terminalserver when 20-25 Users start the program (25*100 = 2500 MB).
|
|
|
| We made some analysis:
|
| So we build a new project which only contains 2 forms. The first form
just
| has one button which starts the second form:
|
|
|
| private void button1_Click(object sender, System.EventArgs e)
|
| {
|
| Form2 frm = new Form2();
|
| frm.ShowDialog();
|
| }
|
|
|
| This second form contains a listview with 10 columns and a button in
order
| to fill it. After pressing the button the listview is filled:
|
|
|
| private void button1_Click(object sender, System.EventArgs e)
|
| {
|
| Random rd = new Random();
|
| Cursor.Current = Cursors.WaitCursor;
|
| ListViewItem item;
|
| string[] s = new string[10];
|
| for (int i=0;i<100000;i++)
|
| {
|
| s[0] = rd.NextDouble().ToString();
|
| s[1] = rd.NextDouble().ToString();
|
| s[2] = rd.NextDouble().ToString();
|
| s[3] = rd.NextDouble().ToString();
|
| s[4] = rd.NextDouble().ToString();
|
| s[5] = rd.NextDouble().ToString();
|
| s[6] = rd.NextDouble().ToString();
|
| s[7] = rd.NextDouble().ToString();
|
| s[8] = rd.NextDouble().ToString();
|
| s[9] = rd.NextDouble().ToString();
|
| item = new ListViewItem(s);
|
| this.lvData.Items.Add(item);
|
| }
|
| }
|
|
|
| During this the memoryusage rises till 180 MB. If I close the second
form
| and return to the first one the memory decreases to 100 MB. This value
didn't
| decrease any more. So we change the code in the first form which opens
the
| second one:
|
|
|
| private void button1_Click(object sender, System.EventArgs e)
|
| {
|
| Form2 frm = new Form2();
|
| frm.ShowDialog();
|
| frm.Dispose(); // NEW Statement
|
| GC.Collect(); // NEW Statement
|
| }
|
|
|
| Now the memory changes after closing the second form from 100 MB to 25
MB.
| This is much better but still not enough! Why does s single application
with
| one form and one button still uses 25 MB? At the beginning it just had 8
MB.
| Run this program at a WTS by 20 Users and you have 500 MB wasted by a
single
| form with just one button!
|
|
|
| We have also read the 1150 pages of ScaleNet.pdf from MSDN. I was
wondering
| about this sentence: AVOID CALLING GC.COLLECT. But this was the only way
to
| reduces the memory in my sampleapplication!
|
|
|
| How can we solve this problem? Is there any better chance to get rid of
this
| waste of memory? At a normal PC it does not matter but it is critical at
a
| Terminal Server.
|
|
|
| Thank you very much
|
|
|
|

Mar 4 '06 #3

"Alexander Overmann" <ao@nospam.conext.de> wrote in message
news:44***********************@read.news.de.uu.net ...
| Dear Willy,
| sure the listview costs a lot of memory but this is at form2. If I close
| form2 and return to form1 the memory does not get become free completely.
|

That's right, this is due to the fact that after you ran the Form2, the CLR
has loaded the framework code for the windows ListView stuff and a buch of
other classes and static variables like strings that are getting interned
(~3MB) but the remaining 25MB is not the problem, the problem is your actual
memory consumption when filling the list. Note that on V2 of the framework
this starts with ~13MB and ends with ~21MB (after a second GC run).

You should never fill a ListView or whatever UI container with that number
of elements.
Why? Well no-one likes to scroll through such a list, it's bad UI design.
Second, memory overhead; you create 1000000 strings objects of 52 bytes each
= 52000000 bytes.
1000000 Listview SubItems of 28 bytes each = 28000000 bytes.
100000 Listview items of 64 bytes each = 6400000
add to that the hashtables used for the listview indexes and you have a
total of 106MB for a single ListView. Note that I'm not counting the randow
doubles(1000000) aand the objects added by the framework classes itself.
This accounts for ~200MB workingset usage, imagine this on a TS with 100
users - 200Mb * 100 = 20 GB, or 5GB for 25 users that would be a real
problem.

That's one thing, next the way you fill the list takes ages (>20 minutes) on
v2 of the framework, while you keep the CPU saturated and this on the UI
thread. This is because you fill the list row per row (using Items.Add(..)),
while you should use AddRange. And as a side effect you prevent the GC to
clean-up the garbage in a timely fashion, that's not a problem when you have
plenty of memory, but on a TS that becomes a problem as you noticed.

Willy.

| But maybe my "wrong way" of filling the listview is the reason? Tell me
how
| you would fill it please and I post the results of ths.
| Thanx
| Alex
|
| btw: Our real-world application currently uses 60MB-150MB for each(!) user
| and we also used all those "hints" found in the web:
| stringbuilder, do not use boxing/unboxing to often, set ref-types to null,
| GC.COLLECT etc.
| Thankx
|
| "Willy Denoyette [MVP]" <wi*************@telenet.be> schrieb im
Newsbeitrag
| news:O2**************@TK2MSFTNGP12.phx.gbl...
| > Please write a small real-world application and run this on a TS, your
| > conclusion based on this piece of code are not relevant. It's right, you
| > only have a few UI elements but you are using a lot of memory because
you
| > are filling a listview with 100000 rows of 10 string values each. Also,
| > the
| > way you fill the list is wrong, it must take ages to fill the list I
| > guess.
| >
| >
| > Willy.
| >
| >
| > "Alexander Overmann" <ao@nospamconnex.de> wrote in message
| > news:44***********************@read.news.de.uu.net ...
| > | Hello,
| > |
| > | currently we encounter several huge memoryproblems running .NET C#
| > | Applications under Windows Terminal Servers/Citrix. Sometimes the
| > program
| > | claims 100 MB which is not very much at a single PC but a pain in the
| > ass
| > at
| > | a Terminalserver when 20-25 Users start the program (25*100 = 2500
MB).
| > |
| > |
| > |
| > | We made some analysis:
| > |
| > | So we build a new project which only contains 2 forms. The first form
| > just
| > | has one button which starts the second form:
| > |
| > |
| > |
| > | private void button1_Click(object sender, System.EventArgs e)
| > |
| > | {
| > |
| > | Form2 frm = new Form2();
| > |
| > | frm.ShowDialog();
| > |
| > | }
| > |
| > |
| > |
| > | This second form contains a listview with 10 columns and a button in
| > order
| > | to fill it. After pressing the button the listview is filled:
| > |
| > |
| > |
| > | private void button1_Click(object sender, System.EventArgs e)
| > |
| > | {
| > |
| > | Random rd = new Random();
| > |
| > | Cursor.Current = Cursors.WaitCursor;
| > |
| > | ListViewItem item;
| > |
| > | string[] s = new string[10];
| > |
| > | for (int i=0;i<100000;i++)
| > |
| > | {
| > |
| > | s[0] = rd.NextDouble().ToString();
| > |
| > | s[1] = rd.NextDouble().ToString();
| > |
| > | s[2] = rd.NextDouble().ToString();
| > |
| > | s[3] = rd.NextDouble().ToString();
| > |
| > | s[4] = rd.NextDouble().ToString();
| > |
| > | s[5] = rd.NextDouble().ToString();
| > |
| > | s[6] = rd.NextDouble().ToString();
| > |
| > | s[7] = rd.NextDouble().ToString();
| > |
| > | s[8] = rd.NextDouble().ToString();
| > |
| > | s[9] = rd.NextDouble().ToString();
| > |
| > | item = new ListViewItem(s);
| > |
| > | this.lvData.Items.Add(item);
| > |
| > | }
| > |
| > | }
| > |
| > |
| > |
| > | During this the memoryusage rises till 180 MB. If I close the second
| > form
| > | and return to the first one the memory decreases to 100 MB. This value
| > didn't
| > | decrease any more. So we change the code in the first form which opens
| > the
| > | second one:
| > |
| > |
| > |
| > | private void button1_Click(object sender, System.EventArgs e)
| > |
| > | {
| > |
| > | Form2 frm = new Form2();
| > |
| > | frm.ShowDialog();
| > |
| > | frm.Dispose(); // NEW Statement
| > |
| > | GC.Collect(); // NEW Statement
| > |
| > | }
| > |
| > |
| > |
| > | Now the memory changes after closing the second form from 100 MB to 25
| > MB.
| > | This is much better but still not enough! Why does s single
application
| > with
| > | one form and one button still uses 25 MB? At the beginning it just had
8
| > MB.
| > | Run this program at a WTS by 20 Users and you have 500 MB wasted by a
| > single
| > | form with just one button!
| > |
| > |
| > |
| > | We have also read the 1150 pages of ScaleNet.pdf from MSDN. I was
| > wondering
| > | about this sentence: AVOID CALLING GC.COLLECT. But this was the only
way
| > to
| > | reduces the memory in my sampleapplication!
| > |
| > |
| > |
| > | How can we solve this problem? Is there any better chance to get rid
of
| > this
| > | waste of memory? At a normal PC it does not matter but it is critical
at
| > a
| > | Terminal Server.
| > |
| > |
| > |
| > | Thank you very much
| > |
| > |
| > |
| > |
| >
| >
|
|
Mar 4 '06 #4

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
by: James Ng | last post by:
I have posted this to the Citrix Developers' forum and have not heard anything yet. So I'd like to see if any other Java developers have experience this problem with their Java application in a...
1
by: Todd | last post by:
I have a .Net windows app running over a Citrix enviornment that normally shows 30 to 50MB of usage according to the server's Task Manager. Our Citrix admin is concerned that this app will...
0
by: tom | last post by:
Hey All, We are hosting our Access XP application via Citrix and are having some confusion about memory. The Citrix server has 2GB of RAM, and what we are perceiving is that only a fraction of...
12
by: Corey Burnett | last post by:
I have a client that has a split database (front-end/back-end). They are also using Access security - MDW file. The front end MDE file, the back end MDB file, and the MDW file are all located on...
16
by: Wayne Aprato | last post by:
I have several Access 97 databases which are split into front end and back end running off a server. The front end mde is shared by 2 or 3 - absolute maximum of 6 concurrent users. This scenario...
33
by: DFS | last post by:
An application I wrote has been deployed on Citrix, and the Citrix admin tells me all users run the same .mde file. There aren't a lot of concurrent users, but even 2 could be cause for concern. ...
5
by: Art | last post by:
Hi, We have some applications that run on a Citrix server. I would like to run one of them, a reporting app, from within a VB.net application. If I log into the Citrix server with remote...
8
by: Blaine Manyluk | last post by:
Greetings... I have some strange problems involving: Access 2000 (9.0.4402 SR-1) Windows 2000 Server 5.00.2195 Service Pack 4 Access apps with Oracle/ODBC back ends One app is a reporting...
12
by: =?Utf-8?B?QXJ0?= | last post by:
Hi, I'm putting together an application in vb.net. I will ultimately need people to be able to run it from home (Normally we're in one office). I can store it on a file server, but this raises...
0
by: DolphinDB | last post by:
The formulas of 101 quantitative trading alphas used by WorldQuant were presented in the paper 101 Formulaic Alphas. However, some formulas are complex, leading to challenges in calculation. Take...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
0
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.