Thanks Chris,
I noticed the same thing that GC.GetTotalMemory(true) and GC.Collect() can
release the memory to Windows.
However I still think the algorithm here is not optimal. Say, my application
occupied 900MB memory, other applications run on the same computer cannot get
those memory. The reason of this is just because my application allocated
that memory ONCE and never use it any more.
I think it is good for .NET to cache that big memory for performance, but it
should be smart enough to release it if the situation is my application does
not need it while other applications need it.
In my sample code, do you think if I should call GC.Collect()? I think if I
do that, it will cause other problems which have been explained in many
articles, for example, it may take long time to collect memory of all
generations...
My one more opinion is: since in this case I know that memory is not used,
is it possible for me to call some functions to just release this paticular
object?
Thanks again.
:
I tried running the test myself.
Calling GC.GetTotalMemory(false) after the method exits shows the array still in memory. This is expected, since a full collection of the large object heap has not yet been
performed. Calling GC.GetTotalMemory(true) shows the memory has been collected. This is using v1.1 SP1.
The amount of vitural memory being used after the collection is the large object heap itself. It expands to fit your large objects, but doesn't shrink when it's emptied. This is
similar to the way Windows manages its virtual memory.
See
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnbda/html/DBGch02.asp for more information
-Chris
--------------------
Chris,
I hope you can write a couple lines of code and reproduce this problem on
your computer.
I am very sure this is a problem, because I examed it by .NET Memory
Profiler, GC.GetTotalMemory() and Task Manager.
Here is the .Net Memory Profiler I used :
http://www.scitech.se/memprofiler/
Also 2 of my coworkers got the same result on their computers respectively.
One thing is obvious - you even don't need any tools to verify - after you
allocate such a big thunk of memory (I tried 900MB), your whole system
becomes slow and never come back until you close the app.
AGAIN, I HOPE EVERYBODY REPEAT MY TEST BEFORE REPLYING. Tell me if the same
problem happens on your machine or not.
:
Hi Imran
Task manager is a bad way to determine how much memory your .NET application is using. Task Manager reports the working set, which is not necessary the same thing.
To verify the GC is working, use GC.GetTotalMemory() or the CLR Profiler, and you should find the memory does in fact get collected.
Thanks
-Chris
--------------------
Thanks for the reply. But I think it is not true in my case. I am using .NET
1.1 with the latest SP1. I also left the application overnight and opened
many other applications. Basically whatever I do, the memory has never been
released.
:
1.1 framework seems to work fine. The GC performs a collect and releases all
the memory very soon (a second) after the array runs out of scope. If you're
using 1.0 then it could very well be what Daniel mentioned.
Imran.
I found a very strange behavior when I write a C# windows application. If I
allocate a huge chunk of memory by an array, the memory will never be
released by .NET.
The problem can be demostrated as follows:
1. Just create the simplest windows form project and add a button and
handler like this:
private void button1_Click(object sender, System.EventArgs e)
{
byte[] aaa = new byte[300000000];
for(int i=0; i<aaa.Length; i++)
aaa
= 10;
}
2. After executing the above code, I observed the memory in Task Manager.
The Commit Charge Total jumped to 300M and the MEM Usage shows the same
thing. The problem is whatever you do the memory usage can never drop
back. I
have tried to open many other applications and NOTHING can make the memory
get released.
3. The variable aaa has gone out of scope, so it does not make any sense
that the .NET still holds the memory. Now the performance of the whole
system
is downgraded.
4. The only thing I can make the memory release to Windows is to call
GC.Collect(). Is this the only way to release that memory? Do I suppose to
do
this?
Can anybody confirm if this is a bug in .NET? Appearantly it does not make
sense to hold the memory FOREVER even if nobody uses it.
Thanks,
Yang.
--
This posting is provided "AS IS" with no warranties, and confers no rights. Use of included script samples are subject to the terms specified at
http://www.microsoft.com/info/cpyright.htm
Note: For the benefit of the community-at-large, all responses to this message are best directed to the newsgroup/thread from which they originated.
--
This posting is provided "AS IS" with no warranties, and confers no rights. Use of included script samples are subject to the terms specified at
http://www.microsoft.com/info/cpyright.htm
Note: For the benefit of the community-at-large, all responses to this message are best directed to the newsgroup/thread from which they originated.