Why should I explicitly call GC collect?

I created an example C # console application that reads file data in an byte array and converts the byte array to the sixth line. This requires a lot of memory, and it does not free up memory after shutdown, I also reset the values โ€‹โ€‹of the variables used.

Here is a sample code:

string filename = @"F:\\AVSEQ09.DAT"; //file size is 32 MB string hexData = null; byte[] fileDataContent = File.ReadAllBytes(filename); if (fileDataContent != null) hexData = BitConverter.ToString(fileDataContent); fileDataContent = null; hexData = null; //GC.Collect(); Console.ReadKey(); 

If I run this code, it takes 433 MB of personal working set, and if I uncomment the call to GC.collect, memmory will go down to 6 MB. Why should I explicitly call GC.collect, is it bad to invoke GC.collect explicitly, how can I free memmory (up to 6 MB) without invoking GC.collect?

+4
source share
6 answers

Garbage collection is a simulation of infinite memory on a machine with finite memory by utilizing memory that a valid program cannot notice is missing.

The above is a very important concept, because, among other things, it emphasizes the fact that the garbage collector does not have to do anything while it can provide memory every time your program requests it.

This may not be the most manageable memory management system, but if your program gets into a situation under memory pressure, the CLR usually starts the garbage collection cycle automatically to reduce some of this pressure. When the system is not under pressure, collection is delayed to avoid frequent unnecessary pauses.

+9
source

You do not need to explicitly call GC.Collect .

It is true that your code uses a lot of memory, but garbage collection has an intelligent algorithm that determines when it should work. It starts when you have lost memory or when you have a sudden increase in memory usage. As long as additional memory remains, the garbage collector does nothing. This greatly improves productivity. If the GC runs all the time, your performance will be terrible.

Setting a variable to null also not required in .NET. The runtime will keep track of which variables are used, and marks them for collection when necessary.

+4
source

You should not use GC explicitly, and not just read ALL of your data. This is a pretty bad practice that you are doing ... When reading from files, you should use using -statement and read in small buffers.

 using(StreamReader sr = new StreamReader(filename)){ //while has data char[] buffer = new char[64000]; // or whatever you like sr.ReadBlock(buffer, 0, buffer.Length); //do your conversion here } 

Look here for StreamReader.ReadBlock() .

+2
source

The .NET CLR manages the memory itself and, if necessary, calls the garbage collector.

In any case, even if you have critical code, you can rely on the .NET CLR to call the garbage collector at the appropriate time. GC is very efficient and frees up memory incredibly fast.

So no problem. Do not call GC, you do not need it. This is .NET.

+1
source

When dealing with such large files and memory structures, consider using threads instead of opening and converting a complete file to memory. In any case, you should not call GC collect.

+1
source

The .NET Garbage Collector is a generational collector. From the point of view of generations, large objects (85K or more) belong to generation 2, because they are collected only when there is a collection of generation 2, which includes the entire generation, this does not happen as often as the assembly of generation 0, because for objects size, large objects are usually arrays (in your case it is a byte []). Second generation collections can be called, for example:

  • Allocation exceeds threshold value 0 or large object. Most GCs are due to allocation on the managed heap.
  • The system is in a low memory situation. This happens when I receive a high memory notification from the OS.
  • System.GC.Collect is called when someone calls GC.Collect on generation 2 (by passing either any arguments to GC.Collect or pass GC.MaxGeneration as an argument)

Therefore, when your system needs memory, it will be more normal to free a byte array without forcing it to free it by calling GC.Collect.

Take a look at this article.

+1
source

All Articles