Garbage Collector Internals in .NET framework

Encoding QR Code in .NET framework Garbage Collector Internals
Garbage Collector Internals
Make QR Code ISO/IEC18004 In .NET Framework
Using Barcode encoder for .NET Control to generate, create QR Code 2d barcode image in .NET framework applications.
Gen 2 0 3 01c51000
Read QR-Code In VS .NET
Using Barcode decoder for .NET Control to read, scan read, scan image in VS .NET applications.
Gen 1 0 3 01c5100c
Encode Barcode In .NET Framework
Using Barcode printer for Visual Studio .NET Control to generate, create bar code image in .NET framework applications.
Gen 0 0 3 01c51018
Recognize Bar Code In .NET Framework
Using Barcode decoder for VS .NET Control to read, scan read, scan image in Visual Studio .NET applications.
Seg 0 (Ephemeral Segment)
Paint QR Code In Visual C#
Using Barcode encoder for .NET Control to generate, create QR Code image in .NET applications.
Obj I
Print QR Code 2d Barcode In Visual Studio .NET
Using Barcode encoder for ASP.NET Control to generate, create QR image in ASP.NET applications.
Obj H
Encode Denso QR Bar Code In VB.NET
Using Barcode generation for VS .NET Control to generate, create QR Code JIS X 0510 image in .NET applications.
Obj G
Data Matrix Drawer In .NET
Using Barcode creator for Visual Studio .NET Control to generate, create Data Matrix image in .NET applications.
Obj F
Code 128 Code Set C Creation In Visual Studio .NET
Using Barcode generator for VS .NET Control to generate, create Code 128 Code Set A image in .NET framework applications.
Obj E
Drawing Barcode In Visual Studio .NET
Using Barcode generation for .NET framework Control to generate, create bar code image in Visual Studio .NET applications.
Obj D
Barcode Generation In .NET
Using Barcode generation for .NET framework Control to generate, create barcode image in .NET framework applications.
Obj C
Intelligent Mail Creator In VS .NET
Using Barcode generation for Visual Studio .NET Control to generate, create USPS Intelligent Mail image in VS .NET applications.
Obj B
Decoding GTIN - 13 In .NET
Using Barcode scanner for Visual Studio .NET Control to read, scan read, scan image in .NET applications.
Obj A
Code39 Recognizer In Visual Studio .NET
Using Barcode reader for .NET framework Control to read, scan read, scan image in .NET applications.
Gen 2
UPC-A Creation In .NET Framework
Using Barcode printer for ASP.NET Control to generate, create Universal Product Code version A image in ASP.NET applications.
Seg 1
GTIN - 13 Creator In Java
Using Barcode generator for Java Control to generate, create EAN13 image in Java applications.
OBJ Q
Code 128C Maker In Java
Using Barcode drawer for Java Control to generate, create Code-128 image in Java applications.
Obj P
Drawing Code-39 In Java
Using Barcode creation for Java Control to generate, create Code 3 of 9 image in Java applications.
Obj O
Code39 Generation In Visual C#
Using Barcode encoder for Visual Studio .NET Control to generate, create Code 39 image in .NET applications.
Obj N
USS Code 128 Creation In Visual C#.NET
Using Barcode drawer for VS .NET Control to generate, create Code 128A image in VS .NET applications.
Obj M
Obj L
Obj K
Obj J
Figure 5-6 Hypothetical managed heap segment
lived, most objects are not expected to live past generation 0 or, at a maximum, generation 1 Objects that live in generation 2 are the oldest objects and get collected very infrequently It is possible that generation 2 can also be part of the ephemeral segment even though generation 2 is not collected as often By looking at an object s address and knowing the address ranges for each of the generations, we can find out which generation an object belongs to How do we know what the generational starting addresses for the CLR heap manager are The answer lies in a command called eeheap The eeheap command displays various memory statistics of data consumed by internal CLR data structures By default, eeheap displays verbose data, meaning that information related to the GC as well as the loader is displayed To display information only about the GC, the gc switch can be used Let s run the command in our existing debug session and see what we get:
0:004> !eeheap -gc Number of GC Heaps: 1 generation 0 starts at 0x01da1018 generation 1 starts at 0x01da100c generation 2 starts at 0x01da1000 ephemeral segment allocation context: none segment begin allocated size 002c7db0 790d8620 790f7d8c 0x0001f76c(128876) 01da0000 01da1000 01da8010 0x00007010(28688) Large object heap starts at 0x02da1000 segment begin allocated size 02da0000 02da1000 02da3250 0x00002250(8784) Total Size 0x289cc(166348) GC Heap Size 0x289cc(166348)
5 MANAGED HEAP AND GARBAGE COLLECTION
5
Managed Heap and Garbage Collection
Part of the output shows clearly the starting addresses of each of the generations If we look at the object addresses in the debug session of our sample application, we can see the following:
<CLR reg> = 0x01da5938 <CLR reg> = 0x01da5948
Both of these addresses corresponding to our objects fall within the address range of generation 0 (starting at 0x01da1018), hence we can conclude that both of them live within the realm of that generation This makes perfect sense because we are currently in the code flow where the objects were just allocated and we are pending a garbage collection If we resume execution of the application and subsequently break execution again the next time we see the Press any key to invoke GC, we should see some difference in which generation the objects belong to If we look at the source code, we can see that prior to invoking a garbage collection, we set the n1 reference to null, which in essence makes the object rootless and one that should be garbage collected Furthermore, n2 is still rooted and as such should be promoted to generation 1 during the garbage collection Let s take a look by following the same process as earlier: find the object addresses, use the eeheap command to find the generational address ranges, and see which generation the object falls into:
0:000> !ClrStack -a OS Thread Id: 0x1910 (0) ESP EIP 0021f394 77709a94 [NDirectMethodFrameSlim: 0021f394] MicrosoftWin32Win32NativeReadConsoleInput(IntPtr, InputRecord ByRef, Int32, Int32 ByRef) 0021f3ac 793e8f28 SystemConsoleReadKey(Boolean) PARAMETERS: intercept = 0x00000000 LOCALS: <no data> 0x0021f3bc = 0x00000001 <no data> <no data> <no data> <no data> <no data> <no data> <no data> <no data>
Garbage Collector Internals
0021f3ec 793e8e33 SystemConsoleReadKey() 0021f3f0 01690111 AdvancedNETDebugging5GenMain(SystemString[]) PARAMETERS: args = 0x01da5818 LOCALS: <CLR reg> = 0x00000000 <CLR reg> = 0x01da5948 0021f644 79e7c74b [GCFrame: 0021f644] 0:000> !eeheap -gc Number of GC Heaps: 1 generation 0 starts at 0x01da6c00 generation 1 starts at 0x01da100c generation 2 starts at 0x01da1000 ephemeral segment allocation context: none segment begin allocated size 002c7db0 790d8620 790f7d8c 0x0001f76c(128876) 01da0000 01da1000 01da8c0c 0x00007c0c(31756) Large object heap starts at 0x02da1000 segment begin allocated size 02da0000 02da1000 02da3240 0x00002240(8768) Total Size 0x295b8(169400) GC Heap Size 0x295b8(169400)
5 MANAGED HEAP AND GARBAGE COLLECTION
The most interesting part of the output is in the eeheap command output We can see now that the generational address ranges have changed slightly More specifically, the starting address of generation 0 has changed from 0x01da1018 to 0x01da6c00, which in essence implies that generation 1 has become bigger (because the starting address of generation 1 remains unchanged) If we correlate the address of our n2 object (0x01da5948) with the generational address ranges that the eeheap command displayed, we can see that the n2 object falls into generation 1 Again, this is fully expected because n2 previously lived in generation 0 and was still rooted at the time of the garbage collection, thereby promoting the object to the next generation I will leave it as an exercise to you to see what happens on the final garbage collection in the sample application Although the SOS debugger extension provides the means of finding out which generation any given object belongs to, it is a somewhat tedious process as it requires that addresses be checked against potentially changing generational addresses within any given managed heap segment Furthermore, there is no concrete way to list all the objects that fall into any given generation, making it hard to get an overall picture of the per generation utilization Fortunately, the SOSEX extension comes to the rescue