0

我的 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 图像)。总共使用了 3643304b(约 3.5MB)的内存。这些图像以大约 20 种不同的形式分布在 UI 元素上。我不知道单独的线程对内存使用有什么影响,但大约有 5-6 个线程同时运行,其中至少 4 个在 95% 的时间处于阻塞状态。

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

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

4

3 回答 3

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;
  }
}

这样,您只在内存中保留该图像的一个实例,这应该会减少整体内存使用量。

于 2010-01-11T14:29:01.947 回答
0

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

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

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

于 2010-01-11T12:35:31.493 回答
0

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

  • 这是另一个正在运行的应用程序
  • 您的应用程序引发了非托管内存泄漏
  • 操作系统(定制的 CE?)有泄漏
  • 或者是其他东西
于 2010-01-12T00:41:17.720 回答