1

我在 .NET CF 应用程序中遇到内存泄漏问题。

使用RPM我发现动态创建控件不会像预期的那样被垃圾收集。在 .NET 窗口窗体中运行同一段代码的行为会有所不同,并且会按我的预期处理控件。

通过 PerfMon 查看 RPM 的输出以了解进程堆计数器:
替代文字

GC 堆:
替代文字

我最好的猜测是,对面板的弱引用是由于某种未知的原因导致对象没有资格进行 GC,可以吗?

请注意:尽管Dispose()解决了示例的问题,但我无法轻松地将其合并到现有应用程序中,因为它无法明确确定对象何时不再使用。

我已经包含了一个简化版本的源代码来说明这个问题:

using System;
using System.Windows.Forms;

namespace CFMemTest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        // Calling this event handler multiple times causes the memory leak
        private void Button1_Click(object sender, EventArgs e)
        {
            Panel uc = new Panel();
            // Calling uc.Dispose() cleans up the object 
        }
    }
}

更新:
1. 调用 GC.Collect() 也不会导致面板被清理。
2. 在 Windows CE 4.2 设备上使用 .NET CF 2.0 SP1。

4

4 回答 4

3

这里的一些附加信息解释了这种行为。

根据 Ilya Tumanov 的说法

所有与 NETCF 相关的 UI 都被有意地从 GC 范围中删除,因此它永远不会被收集。此行为与桌面不同,在 NETCF V3.5 中已更改(除非在兼容模式下运行)。

之所以如此不同,是因为 NETCF 上的托管 UI 类与桌面完全不同。它们是实现可接受性能所需的原生实现的瘦包装器。

我不确定是否有这样的资源。但实际上,您需要知道的是:它永远不会被收集,必须调用 dispose。你实际上也应该在桌面上这样做,但如果你不这样做,那就更宽容了。NETCF 并非如此。

于 2008-10-15T07:29:00.663 回答
2

窗体不会自动释放在其代码中创建的所有控件,因为它无法知道它的存在。要让 Form to Form 在 Disposed 时自动 Dispose,您需要将其添加到 Controls 集合中。

现在,在您的情况下,这可能无济于事。我不知道你的例子是人为的,还是真实的。如果它是真实世界的,那么行为是预期的,因为当变量超出范围时不会收集面板(也不确定它是否在桌面上)。它变得可用于收集,但这仅意味着在下一次收集过程中它将被清扫。除非你引起 GC,否则它不会被释放。

我强烈建议您查看有关 CF 中内存管理的 MSDN 网络广播。它对幕后发生的事情提供了更彻底的解释——远远超过我们在此处的答案中所能提供的。

于 2008-10-14T20:33:26.400 回答
1

你确定你有内存泄漏?.NET Compact Framework 垃圾收集器的工作方式与完整 .NET 框架中的垃圾收集器略有不同。来自Steven Pratschner 的博客

在以下任一情况下启动收集:

  • 已分配 1MB 的对象,

  • 一个应用程序被移到后台,

  • 发生分配内存失败

  • 应用程序调用 GC.Collect。

于 2008-10-14T11:37:05.127 回答
1

我认为您也需要动态删除 Button Click EventHandler,正如您从这个博客中看到的那样:http: //blogs.msdn.com/stevenpr/archive/2007/03/08/finding-managed-memory-leaks-using -the-net-cf-remote-performance-monitor.aspx

它也是来自 Steven Pratschner。

顺便说一下,上面提到的网络广播链接在这里: http ://msevents.microsoft.com/cui/WebCastEventDetails.aspx?culture=en-US&EventID=1032318791&CountryCode=US

希望这可以帮助!

于 2009-01-07T20:59:32.813 回答