Monday, February 12, 2007

Large Object Heap Fragmentation

If an object is 85,000 bytes or larger, it is allocated on the large object heap. Unlike the rest of the managed heap, the Large Object Heap is not compacted due to the cost of moving the large objects.

To avoid Large Object Heap fragmentation, the basic strategy is to determine how to reduce the application's reliance on temporary large objects, which are causing the gaps in the large object heap. If the fragmentation is due to re-allocating buffers, maintain a fixed set of buffers that are reused. If the fragmentation is being caused by concatenation of large numbers of strings, examine whether the System.Text.StringBuilder class can reduce the number of temporary strings created.

Adopted from Debug Leaky Apps: Identify And Prevent Memory Leaks In Managed Code by James Kovacs.

Labels:

Leaking Stack Memory in Managed Code

There are only two real ways to leak stack space. The first is to have a method call that consumes significant stack resources and that never returns, thereby never releasing the associated stack frame. The other is by leaking a thread, and thus that thread's entire stack.

By default, the stack size on modern desktop and server versions of Windows® is 1MB.

Adopted from Debug Leaky Apps: Identify And Prevent Memory Leaks In Managed Code by James Kovacs.

Labels:

Sunday, January 28, 2007

Checking for Leaks in Managed Code

Signs that an application is leaking memory:
  • Throwing an OutOfMemoryException
  • Responsiveness is growing very sluggish because it started swapping virtual memory to disk
  • Memory use is gradually (or not so gradually) increasing in Task Manager

Using PerfMon to determine what kind of memory is leaking:

  • Process/Private Bytes
  • .NET CLR Memory/# Bytes in All Heaps
  • .NET CLR LocksAndThreads/# of current logical Threads

The Process/Private Bytes counter reports all memory that is exclusively allocated for a process and can't be shared with other processes on the system. The .NET CLR Memory/# Bytes in All Heaps counter reports the combined total size of the Gen0, Gen1, Gen2, and large object heaps. The .NET CLR LocksAndThreads/# of current logical Threads counter reports the number of logical threads in an AppDomain.

If an application's logical thread count is increasing unexpectedly, thread stacks are leaking. If Private Bytes is increasing, but # Bytes in All Heaps remains stable, unmanaged memory is leaking. If both counters are increasing, memory in the managed heaps is building up.

Adopted from Debug Leaky Apps: Identify And Prevent Memory Leaks In Managed Code by James Kovacs.

Labels: