Over a million developers have joined DZone.

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

·

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
...snipped…
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)->
0000000002a021c0(MemoryLeak.Schedule)->
0000000002a021d8(System.Byte[])
-----
Finalizer queue:Root:000000002a07058(MemoryLeak.Employee)->
0000000002a07070(MemoryLeak.Schedule)->
0000000002a07088(System.Byte[])
-----
Finalizer queue:Root:000000002a0bf08(MemoryLeak.Employee)->
0000000002a0bf20(MemoryLeak.Schedule)->
0000000002a0bf38(System.Byte[])
…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
  (0000000000d29030->0000000000d29bc0)
generation 1 has 4 finalizable objects
  (0000000000d29010->0000000000d29030)
generation 2 has 8 finalizable objects
  (0000000000d28fd0->0000000000d29010)
Ready for finalization 571 objects
  (0000000000d29bc0->0000000000d2ad98)
Statistics:
…snipped…

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.

Topics:

Published at DZone with permission of Sasha Goldshtein, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}