none
A lot of objects in finalization queue RRS feed

  • Question

  • Hello!

    For unknown reason we have thousands of objects in finalization queue:
    0:002> !FinalizeQueue
    SyncBlocks to be cleaned up: 0
    MTA Interfaces to be released: 0
    STA Interfaces to be released: 0
    ----------------------------------
    generation 0 has 1 finalizable objects (0000000047160bd8->0000000047160be0)
    generation 1 has 0 finalizable objects (0000000047160bd8->0000000047160bd8)
    generation 2 has 371 finalizable objects (0000000047160040->0000000047160bd8)
    Ready for finalization 710207 objects (0000000047160be0->00000000476cbdd8)
    Statistics:
                  MT    Count    TotalSize Class Name
    000007feed51f960        1           24 System.Management.IWbemClassObjectFreeThreaded
    ...
    000007fef3e85270     3150       201600 System.Drawing.SolidBrush
    000007fef3e858f8     5763       276624 System.Drawing.Bitmap
    000007fef3e83108     7374       530928 System.Drawing.Font
    ...
    000007fef3e83790   679426     27177040 System.Drawing.FontFamily
    Total 710579 objects

    Threads shows that almost all objects (including Finalizer) are waiting for objects.

    0:001> !threads
    ThreadCount: 12
    UnstartedThread: 0
    BackgroundThread: 7
    PendingThread: 0
    DeadThread: 3
    Hosted Runtime: no
                                                  PreEmptive                                                Lock
           ID OSID        ThreadOBJ     State   GC     GC Alloc Context                  Domain           Count APT Exception
       0    1 15dc 0000000002313bd0   201a220 Enabled  0000000000000000:0000000000000000 000000000230b9a0     0 MTA
       2    2 13a4 00000000023b3b40      b220 Enabled  0000000000000000:0000000000000000 000000000230b9a0     0 MTA (Finalizer)
       5    3 151c 000000001c270460       220 Enabled  0000000000000000:0000000000000000 000000000230b9a0     0 Ukn
    XXXX    4    0 000000001c28ac30      9820 Enabled  0000000000000000:0000000000000000 000000000230b9a0     0 MTA
    XXXX    5    0 000000001c2a50c0      9820 Enabled  0000000000000000:0000000000000000 000000000230b9a0     0 MTA
       8    6 196c 000000001c2af380      b020 Enabled  0000000000000000:0000000000000000 000000000230b9a0     0 MTA
       9    7 1918 000000001c28a2b0      b220 Enabled  0000000000000000:0000000000000000 000000000230b9a0     0 MTA
      11    8 1908 000000001c2dac90      7020 Disabled 0000000000000000:0000000000000000 000000000230b9a0     2 STA (GC)
      12    9 1858 0000000002310020   180b220 Enabled  0000000000000000:0000000000000000 000000000230b9a0     0 MTA (Threadpool Worker)
      13    a 12a8 000000001c2bca50   200b220 Enabled  0000000000000000:0000000000000000 000000000230b9a0     0 MTA
    XXXX    b    0 000000001c2f4400      9820 Enabled  0000000000000000:0000000000000000 000000000230b9a0     0 Ukn
    XXXX    c 1998 000000001c2fcee0  80010220 Enabled  0000000000000000:0000000000000000 000000000230b9a0     0 Ukn

    0:002> ~*kb

       0  Id: 1668.15dc Suspend: 1 Teb: 000007ff`fffde000 Unfrozen
    RetAddr           : Args to Child                                                           : Call Site
    00000000`7798bc03 : 000007fe`f440c360 000007fe`f4cd55c8 00000000`00000002 00000000`00000000 : ntdll!NtWaitForMultipleObjects+0xa
    000007fe`f460f595 : 00000000`02313bd0 00000000`00000000 00000000`00000000 000007fe`f48ca8bb : KERNEL32!FlsSetValue+0x7b3
    ...

       1  Id: 1668.1450 Suspend: 1 Teb: 000007ff`fffdc000 Unfrozen
    RetAddr           : Args to Child                                                           : Call Site
    00000000`7798bc03 : 00000002`000003f0 00000000`000003f0 00000000`0429b950 00000000`0047ff68 : ntdll!NtWaitForMultipleObjects+0xa
    00000000`77981aa1 : 00000000`02311780 00000000`ffffffff 0000b05e`00000000 00000000`00000200 : KERNEL32!FlsSetValue+0x7b3
    ...

       2  Id: 1668.13a4 Suspend: 1 Teb: 000007ff`fffda000 Unfrozen
    RetAddr           : Args to Child                                                           : Call Site
    00000000`7799c0b0 : 00000000`00000fa0 00000000`00000000 00000000`1c2db740 000007fe`fe2db680 : ntdll!NtWaitForSingleObject+0xa
    000007fe`fe3086b2 : 00000000`000006cc 00000000`1c1e3300 00000000`00000000 00000000`000006cc : KERNEL32!WaitForSingleObjectEx+0xa0
    ...

       3  Id: 1668.15b0 Suspend: 1 Teb: 000007ff`fffd8000 Unfrozen
    RetAddr           : Args to Child                                                           : Call Site
    00000000`77ab7e6e : 00000000`023cec70 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!ZwWaitForWorkViaWorkerFactory+0xa
    00000000`7798be3d : 00000000`023cec70 00000000`00000000 00000000`023cec70 00000000`00000000 : ntdll!RtlRealSuccessor+0x35e
    ...

       4  Id: 1668.1034 Suspend: 1 Teb: 000007ff`fffd4000 Unfrozen
    RetAddr           : Args to Child                                                           : Call Site
    00000000`77ab879d : 00000000`00000000 00000000`00000101 00000000`00000000 00000000`77b87e60 : ntdll!NtWaitForMultipleObjects+0xa
    00000000`7798be3d : 00000000`00000000 00000000`00000000 00000000`00000000 000000af`fd5c4e57 : ntdll!RtlCleanUpTEBLangLists+0x45d
    ...

       5  Id: 1668.151c Suspend: 1 Teb: 000007ff`fffac000 Unfrozen
    RetAddr           : Args to Child                                                           : Call Site
    00000000`7798f65c : 00000000`1c59fe38 00000000`00000000 00000000`1c59fd70 000007fe`00000000 : ntdll!NtRemoveIoCompletion+0xa
    000007fe`ffbc5d0d : 00000000`ffffffff 00000000`00000012 00000000`00000000 000007fe`ffb9036f : KERNEL32!GetQueuedCompletionStatus+0x4c
    ...

       6  Id: 1668.1920 Suspend: 1 Teb: 000007ff`fffaa000 Unfrozen
    RetAddr           : Args to Child                                                           : Call Site
    00000000`7799c0b0 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!NtWaitForSingleObject+0xa
    000007fe`fe2e771c : 00000000`00000478 00000000`00000000 00000000`00000001 00000000`00000478 : KERNEL32!WaitForSingleObjectEx+0xa0
    ...

       7  Id: 1668.1970 Suspend: 1 Teb: 000007ff`fffa8000 Unfrozen
    RetAddr           : Args to Child                                                           : Call Site
    00000000`7799c0b0 : 00000000`00000000 00000000`1c298a90 00000000`00000000 00000000`00000200 : ntdll!NtWaitForSingleObject+0xa
    000007fe`f4abcf48 : 00000000`000003c0 00000000`00000000 00000000`00000000 00000000`000003c0 : KERNEL32!WaitForSingleObjectEx+0xa0
    ...

       8  Id: 1668.196c Suspend: 1 Teb: 000007ff`fffa6000 Unfrozen
    RetAddr           : Args to Child                                                           : Call Site
    00000000`7798bc03 : 00000000`00010002 000007fe`f4a66945 00000000`00f9a468 00000000`1cbfede8 : ntdll!NtWaitForMultipleObjects+0xa
    00000000`778be2b5 : 00000000`00000001 00000000`02b0d010 00000000`00000000 00000000`00000000 : KERNEL32!FlsSetValue+0x7b3
    ...

       9  Id: 1668.1918 Suspend: 1 Teb: 000007ff`fffa4000 Unfrozen
    RetAddr           : Args to Child                                                           : Call Site
    00000000`7799c0b0 : 00000000`00000000 00000000`778bc734 ffffffff`fffffffe 00000000`77986e7a : ntdll!NtWaitForSingleObject+0xa
    000007fe`f45bdd16 : 00000000`00000114 00000000`00000000 00000000`00000000 00000000`00000114 : KERNEL32!WaitForSingleObjectEx+0xa0
    ...

      10  Id: 1668.190c Suspend: 1 Teb: 000007ff`fffa2000 Unfrozen
    RetAddr           : Args to Child                                                           : Call Site
    00000000`7798bc03 : ffffffff`ffffffff 00000000`778bd4c3 00000000`778bd55c 00009966`00ff6666 : ntdll!NtWaitForMultipleObjects+0xa
    00000000`778be2b5 : 00000000`00000001 00000000`1d33fe88 00000000`00000000 00000050`00000030 : KERNEL32!FlsSetValue+0x7b3
    ...

      11  Id: 1668.1908 Suspend: 1 Teb: 000007ff`fffa0000 Unfrozen
    RetAddr           : Args to Child                                                           : Call Site
    000007fe`f4518c93 : 00000000`00000002 00000000`00000000 00000000`00000001 000007fe`f4cceed0 : mscorwks!CompareAssemblyIdentity+0xa2cbe
    000007fe`f49fcb2e : 00000102`66d25a55 00000000`1dfbce98 ffffffff`00000000 00000000`00000000 : mscorwks!StrongNameFreeBuffer+0x93a7
    ...

      12  Id: 1668.1858 Suspend: 1 Teb: 000007ff`ffefe000 Unfrozen
    RetAddr           : Args to Child                                                           : Call Site
    00000000`7799c0b0 : 00000000`00000010 000007fe`f4cd4b7c 00000000`00000000 00000000`00000000 : ntdll!NtWaitForSingleObject+0xa
    000007fe`f45bdd16 : 00000000`000004ec 000007fe`f46a75c8 00000000`00000000 00000000`000004ec : KERNEL32!WaitForSingleObjectEx+0xa0
    ...

      13  Id: 1668.12a8 Suspend: 1 Teb: 000007ff`ffefc000 Unfrozen
    RetAddr           : Args to Child                                                           : Call Site
    00000000`7798bc03 : 000007fe`f440c360 000007fe`f4cd55c8 00000000`000036b7 00000000`00000000 : ntdll!NtWaitForMultipleObjects+0xa
    000007fe`f460f595 : 00000000`1c2bca50 00000000`00000000 00000000`00000001 000007fe`f48ca8bb : KERNEL32!FlsSetValue+0x7b3
    ...

      14  Id: 1668.1994 Suspend: 1 Teb: 000007ff`ffefa000 Unfrozen
    RetAddr           : Args to Child                                                           : Call Site
    00000000`7799c1b8 : 00000000`1f04f808 00000000`000be6e5 00000000`001a2f2b 00000000`00c79856 : ntdll!ZwDelayExecution+0xa
    000007fe`f493658d : 00000000`00000000 000000b4`00000000 ffffffff`ffb3b4c0 00000000`00000000 : KERNEL32!SleepEx+0x88
    ...

    # 15  Id: 1668.1b3c Suspend: 1 Teb: 000007ff`fffae000 Unfrozen
    RetAddr           : Args to Child                                                           : Call Site
    00000000`77b70038 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!DbgBreakPoint
    00000000`7798be3d : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!DbgUiRemoteBreakin+0x38
    ...

    All of them are Unfrozen.


    I wonder how to investigate this issue.

    Thanks,
    Alex


    http://www.alexatnet.com/ - consulting, my blog, articles and discussions
    Thursday, February 18, 2010 4:34 PM

Answers

  • Problem solved: http://support.microsoft.com/kb/828988

    When code runs in MTA thread everything looks fine:

            [STAThread]
            static void Main(string[] args)
            {
                var thread = new Thread(MemoryTest);
                thread.Start();
                while (thread.IsAlive)
                    Thread.Sleep(100);
            }

    Thanks,
    Alex

    http://www.alexatnet.com/ - consulting, my blog, articles and discussions
    • Marked as answer by Alex Netkachov Friday, February 19, 2010 6:52 PM
    Friday, February 19, 2010 6:52 PM

All replies

  • This seems to apply to your case: http://blogs.msdn.com/tom/archive/2008/04/28/asp-net-tips-looking-at-the-finalization-queue.aspx
    (First hit in search for: 'too many objects in the finalization queue')

    From the article:
        ... you can add the -detail switch [to !finalizequeue] and see the Freachable Queue which is all of the objects that are ready to be finalized ....
        When you see the !finalizequeue list showing thousands of objects, that is usually a sign that too many objects have a finalizer.  The best way to troubleshoot this is to look for objects that are not part of the framework and then make sure that they follow the rules we discussed earlier.

    -Karel
    Thursday, February 18, 2010 7:22 PM
    Moderator
  • Hi Alex,

    It looks like your application fails to dispose brushes, bitmaps and fonts.

    using(SolidBrush shadowBrush = new SolidBrush(customColor))
    {
        // use the brush

    }  // dispose


    Use the CLR Profiler to precisly get to the source of your problems.


    Marcel
    Thursday, February 18, 2010 7:44 PM
  • This seems to apply to your case: http://blogs.msdn.com/tom/archive/2008/04/28/asp-net-tips-looking-at-the-finalization-queue.aspx
    (First hit in search for: 'too many objects in the finalization queue')

    From the article:
        ... you can add the -detail switch [to !finalizequeue] and see the Freachable Queue which is all of the objects that are ready to be finalized ....
        When you see the !finalizequeue list showing thousands of objects, that is usually a sign that too many objects have a finalizer.  The best way to troubleshoot this is to look for objects that are not part of the framework and then make sure that they follow the rules we discussed earlier.

    -Karel
    !finalizequeue -detail returns me the following:

    SyncBlocks to be cleaned by the finalizer thread:
           SyncBlock              RCW              CCW  ComClassFactory
            1edf6050                0           d8ef00                0
            1edf6008                0           d8ef80                0
    ...
            1edf5868                0           d8fa80                0
            1edf58b0                0           d8fa00                0
    SyncBlocks to be cleaned up: 32
    MTA Interfaces to be released: 0
    STA Interfaces to be released: 0
    ----------------------------------
    generation 0 has 0 finalizable objects (00000000288a0d90->00000000288a0d90)
    generation 1 has 0 finalizable objects (00000000288a0d90->00000000288a0d90)
    generation 2 has 426 finalizable objects (00000000288a0040->00000000288a0d90)
    Ready for finalization 194287 objects (00000000288a0d90->0000000028a1c508)
    Statistics:
                  MT    Count    TotalSize Class Name
    000007feef38f960        1           24 System.Management.IWbemClassObjectFreeThreaded
    ...
    000007fef3e85270      748        47872 System.Drawing.SolidBrush
    000007fef3e858f8     1663        79824 System.Drawing.Bitmap
    000007fef3e83108     1863       134136 System.Drawing.Font
    000007fef3e83790   186630      7465200 System.Drawing.FontFamily
    Total 194713 objects

    Still about 200K object in queue.

    Selecting several objects from !dumpheap -type System.Drawing.FontFamily and searching roots gives nothing except finalizer queue:

    0:018> !gcroot 00000000081c0fa0 
    Note: Roots found on stacks may be false positives. Run "!help gcroot" for
    more info.
    Scan Thread 0 OSTHread 18a4
    Scan Thread 2 OSTHread ef8
    Scan Thread 5 OSTHread 15a4
    Scan Thread 7 OSTHread 193c
    Scan Thread 10 OSTHread 1604
    Scan Thread 11 OSTHread 5bc
    Scan Thread 13 OSTHread 18f4
    Scan Thread 15 OSTHread 1734
    Scan Thread 16 OSTHread b14
    Finalizer queue:Root:00000000081c0fa0(System.Drawing.FontFamily)

    Adding GC.WaitForPendingFinalizers(); removes all these objects, but I wonder why this objects are not moved to freachable queue nor because of forced GC.Collect() call nor because of regular GC duty.

    For it seems that GC does just does nothing with these objects even when they are not reachable from any root. And there should be reason for this.

    I'm suspecting that I'm just overlooking something but as far as know, things looks as I described.

    Of course I have usings in most of the places in code, but as far as I know GC should take care of disposable (finalizable) objects just when they become dereferenced and move them to freachable queue and then finalize.

    Thanks,
    Alex



    http://www.alexatnet.com/ - consulting, my blog, articles and discussions
    Thursday, February 18, 2010 8:35 PM
  • Hi Alex,

    When a locally declared, further unreferenced FontFamily object goes out of scope, it is not reachable anymore. So it will *not* be moved to the freachable queue (the freachable queue only contains pointers to objects that are still reachable). The FontFamily object can't be collected yet, because it has a Finalize method. So, if you don't call GC.WaitForPendingFinalizers(), it is at the sole discretion of the GC, when the object will be finalized and collected. That's why it is better to embed objects implementing IDisposable in a using code block.

    Marcel
    Friday, February 19, 2010 8:40 AM
  • Hi Alex,

    When a locally declared, further unreferenced FontFamily object goes out of scope, it is not reachable anymore. So it will *not* be moved to the freachable queue (the freachable queue only contains pointers to objects that are still reachable). The FontFamily object can't be collected yet, because it has a Finalize method. So, if you don't call GC.WaitForPendingFinalizers(), it is at the sole discretion of the GC, when the object will be finalized and collected. That's why it is better to embed objects implementing IDisposable in a using code block.

    Marcel
    Hi Marcel,

    You are probably wrong. freachable queue contains pointers to objects that are not reachable and ready for finalization.This clearly described, for example, here:
    The garbage collector scans the finalization queue looking for pointers to the objects which are identified as garbage (e.g. not reachable from any of the roots). And when found, it is moved to freachable queue (so freachable contains pointers to objects that are not reachable from any root).

    And here:
    Garbage Collection: Automatic Memory Management in the Microsoft .NET Framework by Jeffrey Richter
    When a GC occurs, objects B, E, G, H, I, and J are determined to be garbage. The garbage collector scans the finalization queue looking for pointers to these objects. When a pointer is found, the pointer is removed from the finalization queue and appended to the freachable queue (pronounced "F-reachable"). The freachable queue is another internal data structure controlled by the garbage collector. Each pointer in the freachable queue identifies an object that is ready to have its Finalize method called.

    I've summarized what I know about GC in my article: http://www.alexatnet.com/content/net-memory-management-and-garbage-collector

    So I think that I clearly understand that if object has finalizer then its pointer is in the finalization queue. When it becomes unaccessible from any of the roots (!gcroot <objaddress> returns no info) then it becomes garbage and is moved by GC to the freachable queue and then its Finalize method should be called by the finalization thread and on second collection of gen2 garbage it should be removed.

    The problem statement following:
    In my application I have thousands of objects that are ready for finalization (!FinalizeQueue output). Almost all of them (at least several that I randomly selected) are garbage (!gcroot <objaddress> returns no info). Adding GC.WaitForPendingFinalizers() fix the situation. I'm suspecting that something blocks finalization thread (because NtWaitForSingleObject is on top of its stack) but I do not know how to analyze it. I want application works correctly without WaitForPendingFinalizers and know what happens and why it is required.

    Thanks,
    Alex



    http://www.alexatnet.com/ - consulting, my blog, articles and discussions
    Friday, February 19, 2010 12:31 PM
  • Problem solved: http://support.microsoft.com/kb/828988

    When code runs in MTA thread everything looks fine:

            [STAThread]
            static void Main(string[] args)
            {
                var thread = new Thread(MemoryTest);
                thread.Start();
                while (thread.IsAlive)
                    Thread.Sleep(100);
            }

    Thanks,
    Alex

    http://www.alexatnet.com/ - consulting, my blog, articles and discussions
    • Marked as answer by Alex Netkachov Friday, February 19, 2010 6:52 PM
    Friday, February 19, 2010 6:52 PM