You have heard from me before on our memory utilization saga - I will try to
keep this one short and sweet. To make our issue more reproducable, and to
just help me see what going on, I put toghether a utility just to eat memory
and see if we can cause our issue to be more easily reproducable by creating
external pressure. This utility has a List<byte[]>, and every <configurable
time period> it does a List.Add(new byte[configurable size]). It catches
exceptions, cuts the <configurable size> in half, and keeps going. Each time
it adds a byte[] to the list, it also calls GC.GetTotalBytes(true), then
pInvokes to GetGlobalMemory status, and logs:

CA = total number of bytes in all arrays in the list
PM = available physical memory from call to GetGlobalMemoryStatus
VM = available VM in the process slot from call to GetGlobalMemoryStatus
GC = bytes allocated by GC after collection, from GC.GetTotalBytes

I have noticed two interesting behaviors that I am curious if anyone can
explain - first, as CA goes up by X, VM goes down by 2X. Does every managed
byte really cost you two bytes of VM? Second - as I said, when the
allocation fails, it cuts the allocation size in half, and keeps going. I
see VM hit 0, and allocations keep happening. CA and GC keep climbing, PM
keeps dropping, and VM stays 0. I have even caught an OOM and kept going.
Eventually the process just exits memory with no exception - not unexpected,
just finishing the tale.

RE: Confusing VM behavior by Brandon

Brandon
Thu Jan 17 22:58:00 CST 2008

Sorry - platform is WM2K3 (not SE) and netcf 2.0.

"Brandon" wrote:

> You have heard from me before on our memory utilization saga - I will try to
> keep this one short and sweet. To make our issue more reproducable, and to
> just help me see what going on, I put toghether a utility just to eat memory
> and see if we can cause our issue to be more easily reproducable by creating
> external pressure. This utility has a List<byte[]>, and every <configurable
> time period> it does a List.Add(new byte[configurable size]). It catches
> exceptions, cuts the <configurable size> in half, and keeps going. Each time
> it adds a byte[] to the list, it also calls GC.GetTotalBytes(true), then
> pInvokes to GetGlobalMemory status, and logs:
>
> CA = total number of bytes in all arrays in the list
> PM = available physical memory from call to GetGlobalMemoryStatus
> VM = available VM in the process slot from call to GetGlobalMemoryStatus
> GC = bytes allocated by GC after collection, from GC.GetTotalBytes
>
> I have noticed two interesting behaviors that I am curious if anyone can
> explain - first, as CA goes up by X, VM goes down by 2X. Does every managed
> byte really cost you two bytes of VM? Second - as I said, when the
> allocation fails, it cuts the allocation size in half, and keeps going. I
> see VM hit 0, and allocations keep happening. CA and GC keep climbing, PM
> keeps dropping, and VM stays 0. I have even caught an OOM and kept going.
> Eventually the process just exits memory with no exception - not unexpected,
> just finishing the tale.