c# - .NET Memory issues loading ~40 images, memory not reclaimed, potentially due to LOH fragmentation -
well, first foray memory profiling .net app (cpu tuning have done) , hitting bit of wall here.
i have view in app loads 40 images (max) per page, each running ~3mb. max number of pages 10. seeing don't want keep 400 images or 1.2gb in memory @ once, set each image null when page changed.
now, @ first thought must have stale references these images. downloaded ants profiler (great tool btw) , ran few tests. object lifetime graph tells me don't have references these images other single reference in parent class (which design, confirmed meticulously combing through code):
the parent class slideviewmodelbase
sticks around forever in cache, macroimage
property set null when page changed. don't see indication these objects should kept around longer expected.
i next took @ large object heap , memory usage in general. after looking @ 3 pages of images have 691.9mb of unmanaged memory allocated , 442.3mb on loh. system.byte[]
, comes system.drawing.bitmap
bitmapimage
conversion taking pretty of loh space. here conversion code:
public static bitmapsource tobmpsrc( bitmap b ) { var bi = new bitmapimage(); var ms = new memorystream(); bi.cacheoption = bitmapcacheoption.onload; b.save( ms, imageformat.bmp ); ms.position = 0; bi.begininit(); ms.seek( 0, seekorigin.begin ); bi.streamsource = ms; bi.endinit(); return bi; }
i having hard time finding of unmanaged memory going. suspected system.drawing.bitmap
objects @ first, ants doesn't show them sticking around, , ran test made absolutely sure of them disposed , didn't make difference. haven't yet figured out of unmanaged memory coming from.
my 2 current theories are:
- loh fragmentation. if navigate away paged view , click couple of buttons half of ~1.5gb reclaimed. still much, interesting nonetheless.
- some weird wpf binding thing. use databinding display these images , no expert in regards ins , outs of how these wpf controls work.
if has theories or profiling tips extremely grateful (of course) on tight deadline , scrambling bit final part done , working. think i've been spoiled tracking down memory leaks in c++ ... woulda' thought?
if need more info or me try else please ask. sorry wall-o-text here, tried keep concise possible.
this blog post appears descibe seeing, , proposed solution create implementation of stream wraps stream.
the dispose method of wrapper class needs release wrapped stream, can garbage collected. once bitmapimage initialised wrapper stream, wrapper stream can disposed, releasing underlying stream, , allowing large byte array freed.
the bitmapimage keeps reference source stream keeps memorystream object alive. unfortunately, though memorystream.dispose has been invoked, doesn't release byte array memory stream wraps. so, in case, bitmap referencing stream, referencing buffer, may taking lot of space on large object heap. there isn't true memory leak; when there no more references bitmap, these objects (eventually) garbage collected. since bitmap has made own private copy of image (for rendering), seems rather wasteful have now-unnecessary original copy of bitmap still in memory.
also, version of .net using? prior .net 3.5 sp1, there known issue bitmapimage cause memory leak. workaround call freeze on bitmapimage.
Comments
Post a Comment