Memory & GC
var chunks = new List<byte[]> { new byte[30000], new byte[30000], new byte[30000] };
Console.WriteLine($"chunks:{chunks.Count}");
Console.WriteLine($"payload:{chunks.Sum(c => c.Length)}");
chunks.RemoveAt(1);
Console.WriteLine($"remaining-payload:{chunks.Sum(c => c.Length)}");
Console.WriteLine("heap-location:not-measured");
Reveal answer and reasoning
The portable example allocates three independent byte arrays and stores them in a list. chunks:3 is the number of entries. Summing Length returns 90,000 payload bytes. Removing the middle entry leaves two listed arrays and a sum of 60,000. The final line explicitly states heap-location:not-measured because no region inspection or collection observation occurred.
List bookkeeping, array headers, spare list capacity and other process memory are absent from that payload sum. Even the removed array's actual collection time is not established by the output. A compiler or runtime can keep temporary references around, and a future collection must include the relevant area. Use the example to reason about application payload ownership, then use the SDK lab to observe actual CoreCLR counters.
The SDK project creates twenty-four 100,000-byte arrays, removes alternating references, requests a noncompacting full collection, then requests one LOH compaction. It keeps the surviving array container alive through the measurement boundary. The invariant is that twelve entries remain nonnull; exact heap and fragmentation values depend on runtime decisions, other allocations and platform details.
Predict the direction you expect before running, but do not require a specific byte delta as a correctness assertion. Some layouts already have useful free space, and another runtime can make different decisions. Record heap size, fragmentation, committed bytes and GC index together. Repeat a fixed workload in a new process to distinguish a stable effect from one run's incidental allocation history.
What a strong answer covers
- The usual CoreCLR LOH threshold refers to total object size.
- Free fragments, live bytes and committed memory measure different things.
- Compaction changes layout, not the application ownership contract.
Common pitfall
Comparing an array payload length directly with the LOH object-size threshold, or equating free gaps with RSS.
Follow-up questions
- Why can chunking still lead to a final large concatenation allocation?
- Which GC index and fragmentation observations would you compare?
Self-review
Choose what to revisit. These marks are your own assessment and are separate from lesson completion.