Search code examples
c#.netgarbage-collection

GC.TryStartNoGCRegion throws when previous usage exceeded its declared allocations


I can't find a way to call GC.TryStartNoGCRegion if the previous usage exceeded its declared allocations. In that case GC.EndNoGCRegion throws as per documentation, and a new call to TryStartNoGCRegion throws also:

        GC.TryStartNoGCRegion(1000*10000);

        //Allocate more than declared
        for (int i = 0; i < 1100; i++)
        {
            var arr = new byte[10000];
        }

        //Line below throws as it should
        //System.GC.EndNoGCRegion();

        //Not NoGCRegion
        Console.WriteLine(System.Runtime.GCSettings.LatencyMode);

        //Throws with "The NoGCRegion mode was already in progress
        GC.TryStartNoGCRegion(1000*10000);

How to start the no GC mode again?


Solution

  • Try this:

    static void Main(string[] args)
    {
        GC.TryStartNoGCRegion(1000 * 10000);
    
        //Allocate more than declared
        for (int i = 0; i < 1100; i++)
        {
            var arr = new byte[10000];
        }
    
        //Line below throws as it should
        try
        {
            System.GC.EndNoGCRegion();
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
        }
    
        //Not NoGCRegion
        Console.WriteLine(System.Runtime.GCSettings.LatencyMode);
    
        //Throws with "The NoGCRegion mode was already in progress
        Console.WriteLine(GC.TryStartNoGCRegion(1000 * 10000));
    
        Console.ReadLine();
    }
    

    The apparent difference is the necessity to call EndNoGCRegion (and swallow exceptions) before trying to call TryStartNoGCRegion again.