Funny thing just happened. I nearly walked right into Don Box. Stupid little thing really... happens every day. You're heading into the bathroom, Don Box is heading out, you nearly collide. He mutters a simple apology. You stand there thinking: "Cool. That was Don Box, author of Miguel - the musical."
So anyway, this session is brought to you by Maoni Stephens (another woman! yeah! go geek girls!).
Basics: New heap begins with New generation, accessible references keep objects alive, then we compact referenced objects, objects left over are then promoted to older generation
Generations: Three generations (gen0, gen1, gen2) of segments. Most objects die in gen0, but if the object survives it is promoted up the chain to gen1 (in-flight data) and then gen2 (long lived data). gen0 and gen1 are called the ephemeral generations.
GC Heap Segments: GC uses VirtualAlloc to acquire and expire memory (usually in 60MB segments). If it fails to acquire a new segment it throws an OutOfMemoryException. Additional segments reserved, committed, decomitted or deleted as necessary. VM Hoarding (STARTUP_HOARD_GC_VM) startup flag allows you to reuse segments (?) thereby avoiding fragmentation.
Allocation: Costs of allocation (Cheap lock on UP; lock free on MP, moving a pointer forward, clearing memory). Managed allocation (objects that are instantiated together, stay together). Always ask for the exact number of bytes that you need.
Collection: GC kicks in way before the memory gets low... based on the limit for gen0. Whenever your alloc exceeds this limit (a few 100k to a full 60MB segment) the GC kicks in. GC kicks in when 1) there is not enough space in gen0, 2) explicitly calling System.GC.Collect(). It is not recommended to call GC.Collect() because it interfere with the normal operation of the GC. How does the GC kick in: first managed threads are suspended, then the GC runs (marks/compacts), and finally managed threads are resumed. Anything on the stack, handle table, any statics, older generation(s), or in the finalizer queue are marked, compacted and/or aged when the GC runs.
Large Object Heap (LOH): Objects 85KB or larger are only sweeped into the freelist (LOH segments). Collection happens during gen2 GCs.
Collection Cost: Performance counter "% time in GC" can be exposed for tuning. You want this % to be low... larger %'s indicate that items are staying around in the GC too long. gen2 GC's take much longer than gen0 or gen1 GCs (which are relatively cheap). gen2 GC's only occur if the gen2 gets too big. LOH has a different cost model (should reuse LOHs if possible).
Different Flavors of GC: Concurrent GC (workstation) was designed for interative apps and is on by default. Trade some CPU/memory for shorter pause time. Concurrent GCs are only for gen2's and can be turned off via hosting or config. Server GC was designed for apps that have a consistent number of allocations for each request and require high scalibility and throughput. Once Server GC thread is created per CPU running at the highest priority. You must turn on the Server GC in the app.config or machine.config. ASP.NET and SQLCLR can use the Server GC. CLR1.1 (mscorsvr.dll), CLR 2.0 (mscorwks.dll).
Pinning: Most significant change in 2.0 GC. Pinning allowed interop with unmanaged code. Objects get pinned by using the GChandle of type GCHandleType.Pinned, if allowed by language syntax, or if args get pinned by the interop frame. Pinning did cause fragmentation, so GC team moved the gen0 start after the lasted pinned objects
Tags: [PDC05]
posted @ Friday, September 16, 2005 1:48 PM