我正在构建一个小型Windows Phone 8应用程序(基督教 - 东正教日历),它有一个后台代理,应该更新实时磁贴。该应用程序将需要访问手机中的联系人,所以我选择退出互联网访问,所以后端磁贴生成,至少现在是不可能的。我个人不相信有权访问我的联系人和互联网的应用程序。
最近,我的预定代理(生成三个PNG)在我身上启动了OutOfMemoryException。始终如一。我已经使用DeviceStatus来查询和调试它的行为。
如果我调用GC.Collect,它将不会抛出OutOfMemoryException,因此很难将此称为内存泄漏,因为在所有三个tile生成之间。如果它是真正的内存泄漏,一些(大的和/或许多)对象将继续被其他实时/根对象引用,并且没有任何数量的GC.Collect将有所帮助。在我的情况下GC.Collect WILL 帮助。我可以继续使用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();
代码,如果您将检查项目,并不完全像上面那样,因为我已经将几乎所有依赖项包装在适配器和提取的接口中。跨越许多集会。上面的代码是简化版本,它只显示了我认为的相关代码行。
上述代码的一些解释:
问题的核心:我做了一些我不知道的非常错误的事情吗?我脑子里唯一想到的是JPEG生成速度更快,内存消耗更少但是他们不会有我想要的透明度。 这实际上可以称为内存泄漏吗?
LATER EDIT:似乎经过一些调试后,它将其行为从上面的行为改为真正的内存泄漏。我从PNG生成切换到JPEG生成,现在内存较低。输入图像仍然是PNG,但在另一端,JPEG将被吐出。内存占用量比之前的阈值低几兆字节。
第二次编辑:我将逻辑放在按钮上的10.000重复循环中,并且似乎没有太多的内存消耗。我开始认为没有真正的内存泄漏,但只有更高的内存消耗,这足以让脆弱的代理人失望。
答案 0 :(得分:1)
在执行类似的操作时,我必须在调用GC.Collect之前将writeablebitmaps显式设置为null(即使应该是不必要的)。
此外,最好依次创建和销毁(并收集)每个图像,而不是全部创建它们然后将它们全部销毁。这将有助于任何一点的开销。
另请注意,在调试器中跟踪内存使用情况时,调试器会增加大约3mb的开销,而这些开销是您在实时时看不到的。