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

ASP.NET Core MVC and EF Core 1.1
XMLDiff fails to recognize differences correcly?
Can a PrintDialog be modified?
Parse XML generated using C# Classes
How to take input in one line and separately store them in different variables
C# store contents from DB into list
Is it possible for Selenium to open an Excel Workbook pragmatically
MSAL. Detect revoked permissions and perform re-authorization
entity framework ado.net error SaveChanges()
Do I really need to clear a local list?
how to fill one jagged array from another one in c# [closed]
How to listen to events from a URI (C#)? [closed]
Web api internal server error [duplicate]
Stateless 3.0 - State Machine Library Best Practice
Why does regex match capture the whole string as a group in C# when the whole pattern does not have an enclosing parentheses? [duplicate]
How to Transition to new DialogStack in the middle of a FormDialog

Categories

HOME
oauth-2.0
asterisk
twitter-bootstrap
marie
leaflet
virtual-machine
pyspark
cors
customization
weblogic
snappy
microcontroller
pandoc
crash
mediarecorder
browser-cache
docker-compose
olap
tracking
oxid
browsermob
cakephp-2.0
appsettings
nsoperation
web-parts
orange
accordion
caldav
cherrypy
fastboot
inline-assembly
advertising
ps
jira-zephyr
priority-queue
android-cursorloader
windows-10-mobile
cqlsh
kundera
federated
andengine
boost-log
ilog
realloc
mongoid5
motion
nsdateformatter
gem-fury
ninja-forms
ocamlbuild
runner
import.io
openxava
e4
fileopendialog
foreground
konakart
falcon
window.location
radar-chart
chomsky-normal-form
wizard
vanilla-forums
tokudb
eggplant
playn
android-networking
mergecursor
pysvn
crystal-reports-7
launcher
fxmlloader
unityvs
conditional-comments
xmlserializer
redmine-plugins
selenium-grid2
sat4j
disparity-mapping
nest-initiative
scjp
jsmpp
object-oriented-database
fade
dylan
kohana-orm
xrandr
jython-2.5
backbone-views
exi
string-length
django-tinymce
inflate
django-1.4
facebook-winjs-sdk
joomla1.7
httppostedfilebase
recess
xpolog
time-management
j++
asp.net-1.1

Resources

Mobile Apps Dev
Database Users
javascript
java
csharp
php
android
MS Developer
developer works
python
ios
c
html
jquery
RDBMS discuss
Cloud Virtualization
Database Dev&Adm
javascript
java
csharp
php
python
android
jquery
ruby
ios
html
Mobile App
Mobile App
Mobile App