memory - How can I get an OutOfMemoryException in .Net? -
in memory hungry app i'm developing i'm facing outofmemoryexceptions. expected never have kind of exceptions virtual memory. why if needed more ram available os not using hd ram?
you can outofmemoryexception in many different ways. in 32-bit windows, process can use 2gb of virtual address space (i believe it's 1tb in 64-bit applications). keep in mind not ram, different, hence "virtual". forget ram. ram make things quicker. windows memory manager decides if memory program using in ram or disk. when have lots of programs open, less memory loaded physical ram , more on disk. performance terrible, won't have oom exception.
the common way oom exception in .net, try allocate large enough amount of data (something byte array) there not enough contiguous pages of memory available map it, suspect problem lies. means it's possible out of memory exception, if you're requesting new object increase virtual address space amount on 2gb.
"but wait!", 1 might say, "when garbage collector runs, memory compacted, there's contiguous space @ end of heap!"
that true, part. gc collect heap, can thought of 2 heaps, small object heap (soh) , them large object heap (loh). objects, since they're small, live in main generational heap. however, if object above size threshold (this 85k, may have changed), instead allocated on loh.
when memory reclaimed loh, not compacted soh. far expensive memory in loh compacted. memory allocation expensive enough is, , application performance suffer. means heap can , does, become fragmented (this has been improved in .net's 4.0 runtime, vs 2.0 compatible versions).
- let's loh heap looks prior gc:
* = object - = free space |**|***|*|**|*|******|****|**|*****|*******|**|*|***|*****|***|**|-- ^ ^ ^ ^ ^ ^ ^ marked gc
- it once full gc has been done:
* = object - = free space |--|***|*|-- -|******|****|**|-----|*******|--|*|***|-----|***|----
now want allocate array ********
long. runtime going try find spot in there can fit. doesn't. runtime do? well, assuming above represents entire 2gb virtual space , no more memory can allocated, oom exception thrown. have free pages of memory, not enough contiguous.
i have no idea application does, here few things check:
are allocating large array in static type members? long static member points object, never gc'd, if don't use again. static members live on type object, , freed when appdomain unloaded.
are getting allocation size based on user or other input? if, example, reading file header tells length of entry, verifying size of entry correct? i've run off-by-one errors myself, i've read wrong address in file , tried allocate 2tb of memory. verify madness.
if allocating large arrays, really need to? loading data memory doesn't guarantee performance increase. keep in mind program allocated virtual memory space, not ram. if reading file, picking , choosing ones read memory , ones you're streaming?
there's few things can think of, , it's not comprehensive. way run out of memory besides trying address more 2gb of address space full page file, that's less common.
some helpful tools:
windbg (included in windows sdk, part of debugging tools windows) - can use view statistics heap. personal favorite of mine
!dumpheap -stat
,!dumpheap -type [type]
. can use find types using lot of memory.clrprofiler - easier use windbg, less features. gives great graphical @ memory allocations, , can see how many gc handles left when application exited. graph colored type, gives overview of types using memory in heap.
Comments
Post a Comment