我对WPF代码中的内存泄漏感到困惑。我正在将一些3D几何体渲染到多个RenderTargetBitmap,然后将每个3D几何体渲染到一个大型的主RenderTargetBitmap。但是,当我这样做时,我遇到一两分钟的内存泄漏,崩溃了我的应用程序。
我在下面的简化代码中重现了该错误。
private void timer1_Tick(object sender, EventArgs e) {
// if first time, create final stitch bitmap and set UI image source
if (stitch == null) {
stitch = new RenderTargetBitmap(1280, 480, 96, 96, PixelFormats.Pbgra32);
myImage.Source = stitch;
}
// create visual and render to img1
Rect rect = new Rect(new Point(160, 100), new Size(320, 80));
DrawingVisual dvis = new DrawingVisual();
using (DrawingContext dc = dvis.RenderOpen()) {
dc.DrawRectangle(System.Windows.Media.Brushes.LightBlue, (System.Windows.Media.Pen)null, rect);
}
RenderTargetBitmap img1 = new RenderTargetBitmap(640, 480, 96, 96, PixelFormats.Pbgra32);
img1.Render(dvis);
// create visual and render to final stitch
DrawingVisual vis = new DrawingVisual();
using (DrawingContext dc = vis.RenderOpen()) {
dc.DrawImage(img1, new Rect(0, 0, 640, 480));
}
stitch.Clear();
stitch.Render(vis);
}
谁能看到任何明显的错误地方?为什么这段代码会有严重的内存泄漏?
最佳答案
如果使用资源监视器监视RenderTargetBitmap
类的行为,则每次看到该类时,您都会看到丢失500KB的内存。我对您问题的回答是:不要多次使用RenderTargetBitmap
类
您甚至无法释放RenderTargetBitmap的“已用内存”。
如果确实需要使用RenderTargetBitmap
类,只需在代码末尾添加这些行。
GC.Collect()
GC.WaitForPendingFinalizers()
GC.Collect()
这也许可以解决您的问题:
private void timer1_Tick(object sender, EventArgs e) {
// if first time, create final stitch bitmap and set UI image source
if (stitch == null) {
stitch = new RenderTargetBitmap(1280, 480, 96, 96, PixelFormats.Pbgra32);
myImage.Source = stitch;
}
// create visual and render to img1
Rect rect = new Rect(new Point(160, 100), new Size(320, 80));
DrawingVisual dvis = new DrawingVisual();
using (DrawingContext dc = dvis.RenderOpen()) {
dc.DrawRectangle(System.Windows.Media.Brushes.LightBlue, (System.Windows.Media.Pen)null, rect);
}
RenderTargetBitmap img1 = new RenderTargetBitmap(640, 480, 96, 96, PixelFormats.Pbgra32);
img1.Render(dvis);
// create visual and render to final stitch
DrawingVisual vis = new DrawingVisual();
using (DrawingContext dc = vis.RenderOpen()) {
dc.DrawImage(img1, new Rect(0, 0, 640, 480));
}
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
stitch.Clear();
stitch.Render(vis);
}