关于解决CF的OutOfMemoryException的建议

时间:2010-01-08 14:56:25

标签: memory-management compact-framework garbage-collection out-of-memory

我的CF应用程序有一个非常自定义的UI,使用大量图像作为UI元素。当这些位图保存在内存中时,UI会感觉更加流畅。当按需加载时,用户界面很慢,我可以看到按钮逐个出现,看起来非常糟糕。 很长一段时间,这很顺利,但最近我发现应用程序几乎使用了它可以获得的所有内存,即32MB iirc。然后我开始使用远程性能监视器来查看是否可以找到任何清晰的内存占用。

事实证明,使用RPM获取GC堆的有用快照很难:在我可能收到内存不足异常之前关闭,请求快照会导致本机异常立即抛出。我可以偶尔找到一个GC快照。我在这里保存了一个:http://files.zzattack.org/misc/ramis.gclog并在此处截图:http://files.zzattack.org/images/ramisgcsnapshot.png 对我而言,它看起来并不那么麻烦,到目前为止,最大的对象是包含我的资源文件的字节数组(大约3MB的PNG图像)。使用Alltogeher,3643304b(约3.5MB)的内存。这些图像以大约20种不同的形式分布在UI元素上。我不知道单独的线程对内存使用有什么影响,但是大约有5-6个线程同时运行,其中至少有4个线程在95%的时间内处于阻塞状态。

在程序中,当我尝试下载2MB gzip压缩文件时,我将始终收到OutOfMemoryException。当我调用GC.GetTotalMemory(false)时,我发现我确实试图分配比当前可用的更多。调用GC.Collect并再次尝试也不会'解决'/推迟我的问题。

我想就如何解决我的问题提出一些建议。我绝对想要内存中的位图,但也许我可以限制可用于位图的插槽数量,只保留内存中最常用的插槽并按需加载其他插槽。这可能是一个很长的镜头,但也许我可以请求操作系统为我保留更多的内存?我确信应用程序只能在有足够RAM可用的设备上运行。感谢任何帮助,提前谢谢。

3 个答案:

答案 0 :(得分:1)

如果您在多个表单上使用相同的图像,则应考虑将这些位图作为静态变量保存在所有表单都可访问的类中。

public class AppBitmaps
{
  public static Bitmap LogoBitmap = new Bitmap(...);

  public static Bitmap ButtonBitmap = new Bitmap(...);
}

public class Form1
{
  public Form1()
  {
    this.Control1.Image = AppBitmaps.LogoBitmap;
  }
}

这样你只能将该图像的一个实例保留在内存中,这样可以减少整体内存使用量。

答案 1 :(得分:0)

“使用RPM获取GC堆的有用快照很难” 也许你可以为.NET CF尝试一些分析器,我听说过EQATEC分析器,如果它可以帮助你完成线程。

我避免OOM错误的方法是不设计MDI(多文档界面)类型的应用程序,在内存中只有一个表单)并设置为在使用它们之后使所有对象为空(特别是“较重的”对象,如的XMLDocument)。

此外,这可能是相关的: OutOfMemoryException When Creating a Large Bitmap in CF.NET

答案 2 :(得分:0)

如果这是您的应用程序全速工作的快照,那么我建议:

  • 这是另一个正在运行的应用
  • 你的应用程序pinvokes到一个非托管 内存泄漏
  • 操作系统(自定义CE?)有一个 泄漏
  • 或其他