Finalization Queue or F-Reachable Queue? Find Out with SOS

February 25, 2012


It’s 2012, so time for another post related to finalization. This so-often-abused CLR feature has popped up here in the past. A quick recap:

This time, we’ll see how to determine whether a particular object is in the finalization queue (which means it hasn’t been scheduled for finalization yet) or in the f-reachable queue (which means it’s waiting for the finalizer thread to run its finalizer).

Let’s fire up our trusty WinDbg and SOS and look at some heap objects:

0:003> !dumpheap -stat
000007ff00023b78     1340        32160 MemoryLeak.Schedule
000007ff00023aa0     1340        32160 MemoryLeak.Employee
000007fef5ff7b08      435        44400 System.String
000007fef5fe58f8      310        67120 System.Object[]
00000000005387f0      577      2680608      Free
000007fef5fffb48     1345     13432600 System.Byte[]
Total 6231 objects

Okay, what are these schedules, employees, and byte arrays running around?

0:003> .foreach (obj {!dumpheap -mt 000007fef5fffb48 -short}) {!gcroot obj; .echo —–}
…edited for clarity…
Finalizer queue:Root:000000002a021a8(MemoryLeak.Employee)->
Finalizer queue:Root:000000002a07058(MemoryLeak.Employee)->
Finalizer queue:Root:000000002a0bf08(MemoryLeak.Employee)->
…many more of these snipped…

Now, are these Employee objects rooted at the finalization queue or the f-reachable queue? Unfortunately, !gcroot does not tell. However, !FinalizeQueue shows the queue statistics:

0:003> !FinalizeQueue
SyncBlocks to be cleaned up: 0
MTA Interfaces to be released: 0
STA Interfaces to be released: 0
generation 0 has 370 finalizable objects
generation 1 has 4 finalizable objects
generation 2 has 8 finalizable objects
Ready for finalization 571 objects

Note the information on finalizable objects vs. objects that are ready for finalization. The former are in the finalization queue, the latter are in the f-reachable queue.

But now suppose that you have an individual object and you want to determine whether it’s in the finalization queue or the f-reachable queue. All you need to do is check in which array it is contained by searching memory with the s command:

0:003> s -q 0000000000d29bc0 0000000000d2ad98 0000000002a0bf08
00000000`00d29da8  00000000`02a0bf08 00000000`02a10db8
0:003> s -q 0000000000d28fd0 0000000000d29bc0 0000000002a0bf08

Okay, so 0000000002a0bf08 is in the f-reachable queue, waiting for the finalizer thread.

I am posting short updates and links on Twitter as well as on this blog. You can follow me: @goldshtn
This blog post was also cross-posted to CodeProject.

Add comment
facebook linkedin twitter email

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>



  1. Steve JohnsonFebruary 25, 2012 ב 7:19 PM

    Have you checked out !sosex.finq and !sosex.frq?
    Those commands give you much better information than SOS.

  2. AlexanderFebruary 29, 2012 ב 10:11 AM

    Great article , I am so glad that I have visited your site.I was looking for this information.

  3. UdibMarch 7, 2012 ב 10:12 PM

    That is so cool!
    great post!