Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C#, Why is the GC running several times per second? [closed]

I'm working on a program that creates interactive charts. However, the following issue occurs even if the program's rendering layer is disabled.

On certain screens in my application, according to the Visual Studio 2015 Diagnostic Tools, the GC is running back to back approximately 4 times per second, killing my application's performance (from 120fps to as low as 15fps).

I took some memory snapshots expecting to see unexpected allocations, but according to the snapshots there's only one or two allocations and collections of System.Internal.HandleCollector+HandleType every few seconds, which appears to be normal, even when the issue isn't occurring.

Some other things I've noticed:

  • This happens on multiple machines.
  • This happens with or without the debugger attached.
  • Most of the application's CPU time is in clr.dll.
  • The reason for each GC run is listed as "Small object heap allocation", even when there's no observable allocations in the snapshots.

At this point I'm stumped. Has anyone seen this happen or know where I should start debugging?

like image 789
C. Olimar Avatar asked Apr 11 '16 18:04

C. Olimar


2 Answers

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 that is used by allocated objects on the managed heap surpasses an acceptable threshold. This threshold is continuously adjusted as the process runs.

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

Perhaps you are meeting one of the three conditions listed above. It seems that your application is using a lot of memory and so Garbage Collection is running to try to clean up some objects to try to free up some memory.

It could also be possible that GC.Collect() is in your code somewhere and is causing the Garbage Collector to run again.

Here are some troubleshooting guidelines related to garbage collection. One section in particular seems to relate to the issue that you are having. Under the section marked as "Issue: CPU Usage During a Garbage Collection Is Too High" it says:

CPU usage will be high during a garbage collection. If a significant amount of process time is spent in a garbage collection, the number of collections is too frequent or the collection is lasting too long. An increased allocation rate of objects on the managed heap causes garbage collection to occur more frequently. Decreasing the allocation rate reduces the frequency of garbage collections.

You can monitor allocation rates by using the Allocated Bytes/second performance counter. For more information, see Performance Counters in the .NET Framework.

The duration of a collection is primarily a factor of the number of objects that survive after allocation. The garbage collector must go through a large amount of memory if many objects remain to be collected. The work to compact the survivors is time-consuming. To determine how many objects were handled during a collection, set a breakpoint in the debugger at the end of a garbage collection for a specified generation.

like image 183
Tophandour Avatar answered Oct 27 '22 09:10

Tophandour


Try to change your app.config with this and make a run

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

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

like image 32
Sergei Zinovyev Avatar answered Oct 27 '22 09:10

Sergei Zinovyev