Memory usage of strings (or any other objects) in .Net

I wrote this little test program:

using System; namespace GCMemTest { class Program { static void Main(string[] args) { System.GC.Collect(); System.Diagnostics.Process pmCurrentProcess = System.Diagnostics.Process.GetCurrentProcess(); long startBytes = pmCurrentProcess.PrivateMemorySize64; double kbStart = (double)(startBytes) / 1024.0; System.Console.WriteLine("Currently using " + kbStart + "KB."); { int size = 2000000; string[] strings = new string[size]; for(int i = 0; i < size; i++) { strings[i] = "blabla" + i; } } System.GC.Collect(); pmCurrentProcess = System.Diagnostics.Process.GetCurrentProcess(); long endBytes = pmCurrentProcess.PrivateMemorySize64; double kbEnd = (double)(endBytes) / 1024.0; System.Console.WriteLine("Currently using " + kbEnd + "KB."); System.Console.WriteLine("Leaked " + (kbEnd - kbStart) + "KB."); System.Console.ReadKey(); } } } 

Output in assembly Release:

 Currently using 18800KB. Currently using 118664KB. Leaked 99864KB. 

I assume that calling GC.collect will delete the highlighted lines as they go out of scope, but it doesn't seem to be that way. I do not understand and cannot find an explanation. Maybe someone here?

Thanks Alex

+6
c # memory
source share
2 answers

You look at the amount of private memory - the managed heap will expand to accommodate the lines, but it will not free the memory back to the operating system when the lines are garbage collected. Instead, the managed heap will be larger, but it will have a lot of free space - so if you create more objects, this will not require an expansion of the heap.

If you want to look at the memory used in the managed heap, see GC.GetTotalMemory . Please note that due to the difficulty of collecting garbage, it has a certain amount of wool.

+9
source share

Indeed, I used the size of a personal mem, because the one that is closest to one in Process Explorer

if I rewrite the program using GC.GetTotalMemory as follows:

 using System; namespace GCMemTest { class Program { static void Main(string[] args) { System.GC.Collect(); long startBytes = System.GC.GetTotalMemory(true); { string[] strings = new string[2000000]; for (int i = 0; i < 2000000; i++) { strings[i] = "blabla" + i; } strings = null; } System.GC.Collect(); long endBytes = System.GC.GetTotalMemory(true); double kbStart = (double)(startBytes) / 1024.0; double kbEnd = (double)(endBytes) / 1024.0; System.Console.WriteLine("Leaked " + (kbEnd - kbStart) + "KB."); System.Console.ReadKey(); } } } 

Then output:

Leak 0K.

Only when I have "stringings = null;" this is so, delete it and I will skip 100 MB. This means that the local area in the main procedure does not free the array. If I translate this part into the static Test method and call it instead, I will skip a few bytes. I suggest that I should learn from this that local regions are ignored by the GC.

0
source share

All Articles