4

当我在带有附加调试器的设备上启动此示例程序时,会发生严重错误。

这是我们实际应用程序中发生的事情的精简版本。

我发现的是:

  • 必须附加调试器
  • 必须以某种方式填充内存(我认为这将强制垃圾收集)
  • 垃圾(位图)对象必须存在。其他对象可能会导致相同的错误
  • 必须显示表单(如果使用 Application.Run() 或 ShowDialog,则没有区别)

然后,当表单可见并且 GC 收集位图时,会发生严重错误。

我正在运行带有 .NET Compact Framework 3.5 的 WindowsCE 6 R3。

static class Program {

    static void Main() {
        // Fill up memory - Depends on device
        var memory = new int[100000 * 150];

        // Settings the priority higher will raise the error earlier.
        // With Priority set to Normal the EXE won't get freed correct.
        // Without this line i have to reboot the CE after every test run...
        Thread.CurrentThread.Priority = ThreadPriority.Highest;

        // 80 is just random choosen. The error occurs also with 30 Bitmaps...
        for (int o = 1; o < 80; o++) {
            // Create a Bitmap and don't free it manually. The
            // The garbage collector will take care of it :)
            var bitmap = new Bitmap(100, 100);

            // When i dispose the Bitmap, everything works fine...
            //bitmap.Dispose();
        }

        // Force a GC run
        System.Diagnostics.Debug.WriteLine(GC.GetTotalMemory(true));

        // Then error occurs when the form is shown.
        System.Windows.Forms.Application.Run(new System.Windows.Forms.Form());
    }
}

我已经找到了类似的问题,但没有答案...

到目前为止我已经尝试过:

  • 手动清理所有资源。我已经搜索了所有位图创作并处理或缓存了它们。错误仍然存​​在,不仅仅是位图不好......
4

2 回答 2

1

我有一个理论,那就是系统正在交换。如果调试器尝试检索自己的大小超过CE 的分页池大小的变量的内容,我可以想象这是死锁。调试器停止系统读取数据,但系统无法提供内容,因为它无法交换数据。使用 IOCTL_HAL_GET_POOL_PARAMETERS,您应该能够检测系统是否正在交换。

于 2013-05-05T17:29:57.040 回答
0

这很难找到答案。

当您说 时a serious error occurs,我猜您看到的是OutOfMemoryException

垃圾收集器(GC) 在框架为 GC 分配时间或调用它时运行。

如果您创建/使用内存的速度比框架调用 GC 的速度快,那么您可能会耗尽内存——尤其是在 CF 应用程序中。

上面的 MSDN 链接说明了以下内容:

.NET Framework 的垃圾收集器管理应用程序的内存分配和释放。每次使用 new 运算符创建对象时,运行时都会从托管堆中为对象分配内存。只要托管堆中有可用的地址空间,运行时就会继续为新对象分配空间。然而,记忆不是无限的。最终,垃圾收集器必须执行收集以释放一些内存。垃圾收集器的优化引擎根据正在进行的分配确定执行收集的最佳时间。当垃圾收集器执行收集时,它会检查托管堆中不再被应用程序使用的对象,并执行必要的操作来回收它们的内存。

为了解决这个问题,您需要在完成资源时释放它们。如果您稍后需要该数据,您可以将资源保存到某种媒体(闪存数据、硬盘驱动器等)以供以后检索。

有关这方面的更多信息,您可以阅读 Steven Pratschner 的博客,标题为 .Net Compact Framework 垃圾收集器概述

于 2013-05-03T16:28:21.357 回答