C # Why does the GC work several times per second?

I am working on a program that creates interactive charts. However, the following problem occurs even if the rendering layer of the program is disabled.

On some screens of my application, in accordance with the Visual Studio 2015 diagnostic tools, GC runs about 4 times per second, which reduces the performance of my application (from 120 frames per second to 15 frames per second).

I took some snapshots, expecting to see unexpected allocations, but according to the snapshots, there are only one or two allocations and the System.Internal.HandleCollector + HandleType collections every few seconds, which seems normal even if the problem is not Running.

Some other things that I noticed:

  • This happens on several machines.
  • This happens with or without a debugger application.
  • Most of the processor time of the application is in clr.dll.
  • The reason for each GC run is indicated as a “Pile of Small Objects Distribution”, even if there are no observed distributions in snapshots.

At this moment I am at a standstill. Has anyone seen this happen or do you know where I should start debugging?

+5
source share
3 answers

Try changing your app.config with this and run a run

<configuration> <runtime> <gcServer enabled="true"/> </runtime> </configuration> 

More interesting details about GC here https://msdn.microsoft.com/en-us/library/ee787088(v=vs.110).aspx

+2
source

From https://msdn.microsoft.com/en-us/library/ee787088(v=vs.110).aspx

Garbage collection occurs when one of the following conditions is true:

The system has low physical memory.

The memory used by the allocated objects in the managed heap exceeds the allowable threshold. This threshold is continuously adjusted as the process starts.

The GC.Collect method is called. In almost all cases, you do not need to call this method because the garbage collector runs continuously. This method is mainly used for unique situations and testing.

You may meet one of the three conditions listed above. It seems that your application uses a lot of memory, and therefore the Garbage Collection is working, trying to clear some objects in order to try to free up memory.

It is also possible that GC.Collect() is located somewhere in your code and causes the garbage collector to reload.

Here are some troubleshooting tips for garbage collection. In particular, one section refers to the issue that you have. In the section labeled “Problem: CPU usage during garbage collection is too high,” says:

CPU usage will be high during garbage collection. If a significant part of the process time is spent on garbage collection, the number of assemblies is too frequent or the collection is too long. Increasing the speed of placing objects on a managed heap leads to the fact that garbage collection occurs more often. Reducing the distribution speed decreases the frequency of garbage collection.

You can control distribution levels using a byte / second counter. For more information, see Performance Counters in the .NET Framework.

The duration of the collection is primarily a factor in the number of objects that survive after isolation. The garbage collector must go through a large amount of memory if there are many objects left. Work to reduce survivors takes a lot of time. To determine how many objects were processed during the collection, set a breakpoint in the debugger at the end of the garbage collection for a specific generation.

+2
source

You should check the code on where you call GC. It usually works much less than 4 times per second. Attach an instance with a debugger or profiler that has a problem to find where the GC is being called. Perhaps this is in a third-party library. Or some code that you did not think to check.

0
source

Source: https://habr.com/ru/post/1246893/


All Articles