WriteableBitmap的或PNG作家内存泄露?(WriteableBitmap or PNG

2019-10-18 19:15发布

我建立一个小型的Windows Phone 8的应用程序(如基督教,东正教历),其具有应更新动态磁贴背景代理。 该应用程序将需要访问联系人的电话,所以我选择了退出的互联网接入使后端区块生成,至少现在出了问题。 我个人并不相信有我的接触和对Internet的访问的应用程序。

最近我定剂(其产生三个PNG格式)开始对我OutOfMemoryException异常-ING。 始终如一。 我用DeviceStatus查询和调试它的行为。

这很难,如果我调用GC.Collect它不会抛出OutOfMemoryException异常调用此内存泄漏,因为所有这三个瓦代之间。 如果它是一个真正的内存泄露一些(大和/或多个)对象会被其他现场/根的对象仍然引用,并没有GC.Collect的量会有所帮助。 在我的情况GC.Collect的有所帮助。 我可以继续使用GC.Collect的,但我觉得脏这样做。

正如我开发的应用程序自由和开放源码您可以详细地在目前的发展状态下查看项目的所有代码http://orthodoxcalendar.codeplex.com

区块生成包括采取一个背景和重叠在该背景其他两个图像。 基本上为三个PNG图像的生成我做的

var bytes1 = (byte[])resourceManager.GetObject(resourceName1);
var stream1 = new MemoryStream(bytes);

var bytes2 = (byte[])resourceManager.GetObject(resourceName2);
var stream2 = new MemoryStream(bytes);

var bytes3 = (byte[])resourceManager.GetObject(resourceName3);
var stream3 = new MemoryStream(bytes);

var writeableBitmap1 = BitmapFactory.New(size.Width, size.Height).FromStream(stream1); // background
var writeableBitmap2 = BitmapFactory.New(size.Width, size.Height).FromStream(stream2); // first overlay
var writeableBitmap3 = BitmapFactory.New(size.Width, size.Height).FromStream(stream3); // second overlay

writeableBitmap1.Blit(new Point(0, 0), writeableBitmap2, new Rect(0, 0, width2, height2), Colors.White, BlendMode.Alpha);
writeableBitmap1.Blit(new Point(0, 0), writeableBitmap3, new Rect(0, 0, width3, height3), Colors.White, BlendMode.Alpha);
writeableBitmap1.DrawText("Some text", new Point(5, 139), Color.Black, 17);
writeableBitmap1.Invalidate(); // flatten things

using(var outputStream = new WhateverStream())
{
  PNGWriter.Write(writeableBitmap1, outputStream);
}

writeableBitmap1.SetSource(new MemoryStream(MiscData.MinimumPng)); // set the writeable bitmap to a 1x1 transparent PNG to, hopefully, force it to release unamanaged memory or other stuff
writeableBitmap2.SetSource(new MemoryStream(MiscData.MinimumPng));
writeableBitmap3.SetSource(new MemoryStream(MiscData.MinimumPng));

stream1.Dispose();
stream2.Dispose();
stream3.Dispose();

的代码,如果你签出项目,是不完全像上面,因为我已经包裹在适配器和提取接口几乎全部依赖。 在许多组件。 上面的代码是简化版这只是表明,我认为是,相关的代码行。

以上代码的一些解释:

  • 所有这些代码是在Dispatcher.BeginInvoke里面的后台代理运行,因为你似乎无法操作任何其他线程比UI线程WritableBitmap
  • PNG数据被存储在另一组件RESX。 我知道这养肥组装,但我想这能重复使用跨平台的组件是PCL
  • 直接创建WriteableBitmap的使用字节数组似乎是在一个神秘的方式失败,所以我包裹它一个MemoryStream并以某种方式,这样一来,它的工作原理
  • 该PNG作家摘自工具堆栈 。
  • 这是不可行的,因为有“先覆盖”多个版本,以预先生成的图像,“第二个覆盖”,并且大多是“一些文本”。 这将意味着图像数以万计,至少。

问题的心脏: 我做得非常错误的是我不知道的? 在我的脑海里跳出的唯一的事情就是JPEG图像生成速度更快,内存消耗少,但他们不会有透明度,这是我的愿望。 这能叫实际内存泄漏?


稍后编辑:看来,经过一些调试它改变了其行为从一个上面一个真正的内存泄漏。 我从PNG代切换到JPEG生成和存储现在低。 输入图像仍PNG,但在另一端的JPEG会吐。 内存占用就跌破前期阈值(S)几兆。


第二个编辑:我把逻辑10.000重复循环的一个按钮,似乎没有太多的内存消耗。 我开始认为有没有真正的生成过程中内存泄漏而只是更高的内存消耗,这足以使脆弱的代理了。

Answer 1:

在做类似的事情,我不得不调用GC.Collect的前明确设置writeablebitmaps为空(即使应该是不必要的)。

此外,它可能是更好反过来创建和销毁(收集),每一个图像,而不是创建所有这些,然后摧毁它们。 这将有助于在任何一个点上的开销。

另外请注意,跟踪调试器中的内存使用时,调试器增加了约开销3MB,你不会住的时候看到的。



文章来源: WriteableBitmap or PNG writer memory leak?