c#


Memory leak in RenderTargetBitmap


I'm using a RenderTargetBitmap to render a set of controls in order to generate a PDF. The following code segment is the relevant section:
public Drawing.Image RenderPageBitmap()
{
RenderTargetBitmap bit = null;
Drawing.Bitmap bmp = null;
try
{
bit = new RenderTargetBitmap(ImageSource.PixelWidth, ImageSource.PixelHeight, 96, 96, PixelFormats.Pbgra32);
var viewBox = GetPageXaml(); //This method loads some prebuilt XAML from an embedded resource, setting the DataContext as needed.
var siz = new Size(bit.PixelWidth, bit.PixelHeight);
viewBox.Measure(siz);
viewBox.Arrange(new Rect(siz));
viewBox.UpdateLayout();
var draw = new DrawingVisual();
using (var graph = draw.RenderOpen())
graph.DrawRectangle(new BitmapCacheBrush(viewBox), null, new Rect(siz));
bit.Render(draw);
bit.Freeze();
bmp = new Drawing.Bitmap(bit.PixelWidth, bit.PixelHeight, Imaging.PixelFormat.Format32bppPArgb);
var data = bmp.LockBits(new Drawing.Rectangle(Drawing.Point.Empty, bmp.Size), ImageLockMode.WriteOnly, Imaging.PixelFormat.Format32bppPArgb);
{
bit.CopyPixels(Int32Rect.Empty, data.Scan0, data.Height * data.Stride, data.Stride);
}
bmp.UnlockBits(data);
return bmp;
}
catch (Exception)
{
bmp?.Dispose();
throw;
}
finally
{
bit?.Clear();
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
}
}
Even following other answers on StackOverflow and other forums (like clearing the bitmap and performing a garbage collection) doesn't seem to solve the issue. Each loop of this code can leak ~100MB of memory, which means I quickly hit the ~2GB limit of 32-bit processes.
The leak seems to occur on the RenderTargetBitmap.Render method exclusively, even the DrawingContext.DrawRectangle call doesn't noticeably increase memory usage.
Is there anything I can do to solve this problem?
You return the Bitmap to somewhere. Make sure you Dispose the Bitmap instance once you are done with it. What you are doing in the finally is useless when there is memory leak. If there are references GC wouldn't collect it.
Each loop of this code can leak ~100MB of memory, which means I
quickly hit the ~2GB limit of 32-bit processes.
Are you assuming there is a memory leak? May be there is no memory leak. I would get a good memory profiling tool and test this.
I have used ANTS Memory profiler and I find it good (it comes with 14 days trial). Just execute your logic a few times and see the Instance List if anything is growing. If so, look at the Retention graph to see what holds onto it. That will tell you what exactly happening. Root causes for memory leaks are quite difficult to guess sometimes, fortunately there are good tools for that.
Based on my inspection, draw allocates a DrawingVisual object.
Unless Render() frees it inside, you should explicitly delete the DrawingVisual object.

Related Links

Do I need to make my class static to use a static method?
Is locking access to a bool required or is it Overkill
Referencing StreamReader in two methods
Convert tiff byte array to pdf byte array using itextsharp with C#
Eraser functionality for an drawing application
Mark deprecated fields in WCF contract
File.AppendAllText create subdirectory if doesn't exist?
Microsoft PolicyInjection Create too slow
Simple conditional LINQ query in Entity Framework 4
Properties.Settings.Default.Save(); -> Where is that file
Error message in google recaptcha
How can I invoke `EditorExtensions.EditorFor` in my HtmlHelper?
Ignoring XML tags in XSL
Object Reference Not Set to an Instance within LINQ to SQL Query
ajax control toolkit calendar for dynamically generated textboxes
Exchange Managed API: Why is the event not fired when a item is deleted?

Categories

HOME
logging
oop
indexing
azure-documentdb
crash
symfony-sonata
download
sdk
powerquery
schema
install
segmentation-fault
token
google-app-maker
runtime
spring-data-solr
fine-uploader
browsermob
element
yui
multibinding
vivado-hls
geography
hapijs
views
loader
autologin
computation-theory
android-wifi
webgl-earth
border-layout
oracle-bpm-suite
armadillo
office-interop
collation
quartz
flume-ng
definition
binary-decision-diagram
geminabox
stream-socket-client
denodo
google-cloud-shell
cloudconvert
node-java
typewriter
turbolinks
android-tabs
consolidation
eclipse-mars
virtualenvwrapper
disconnect
instaparse
vga
recurring
avi
treelist
jcalendar
ewam
controlpanel
sdkman
traminer
cyberduck
syncano
callfire
vectordrawable
system.diagnostics
copy-on-write
perfect-scrollbar
uiblureffect
report-builder2.0
mind-manager
apache-pivot
xmlserializer
adabas
xcode5.1
usersettings
nsautoreleasepool
gwt2
ntdll
expresso-store
states
aspmenu-control
parsec
maven-eclipse-plugin
overlays
windows-xp-embedded
virtual-destructor
chars
activescaffold
newspeak
coderush-xpress
authkit
zend-acl
cstring
j++
office-2003

Resources

Encrypt Message



code
soft
python
ios
c
html
jquery
cloud
mobile