.NETCF 中的内存泄漏 - 创建动态控件?

发布于 2024-07-06 20:39:44 字数 1288 浏览 9 评论 0原文

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

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

通过 PerfMon 查看 RPM 的输出,了解进程堆计数器:
alt text

GC 堆:
alt text

我最好的猜测是,对面板的弱引用由于某种未知原因而没有进行符合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。

I have a problem with a memory leak in a .NET CF application.

Using RPM I identified that dynamically creating controls are not garbage collected as expected. Running the same piece of code in .NET Window Forms behave differently and disposes the control as I expected.

See the output from RPM via PerfMon for the Process Heap counter:
alt text

GC Heap:
alt text

My best guess is that the Weak Reference to the Panel is for some unknown reason not making the object eligible for GC, can it be?

Please note: Even though Dispose() solves the problem for the sample, I can't easily incorporate it into the existing application as it is not as clear cut to determine when the object is no longer in use.

I have included a simplified version of the source to illustrate the problem:

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

Update:
1. Calling GC.Collect() also doesn't result in the panels being cleaned up.
2. Using .NET CF 2.0 SP1 on a Windows CE 4.2 device.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

太阳公公是暖光 2024-07-13 20:39:44

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

根据 Ilya Tumanov 的说法:

NETCF 上所有与 UI 相关的内容都是
故意从 GC 范围中删除,以便
它永远不会被收集
。 这种行为
与桌面不同,并且已经
NETCF V3.5 中的更改(除非运行
在兼容模式下)。

这是如此不同,因为托管 UI
NETCF 上的课程完全
与桌面不同。 他们很瘦
本机实现的包装器
这是达到可接受的目标所需要的
性能。

我不确定是否有这样的资源。
但实际上,您需要知道的是:
它从未被收集,必须调用
处置。 你实际上应该这样做
也可以在桌面上使用,但如果你不这样做
它的方式更加宽容。 不久
NETCF。

Some additional information here that explains this behaviour.

According to Ilya Tumanov:

Everything UI related on NETCF is
intentionally removed from GC scope so
it is never collected
. This behavior
is different from desktop and has been
changed in NETCF V3.5 (unless running
in compatibility mode).

It is so different because managed UI
classes on NETCF are completely
different from desktop. They are thin
wrappers over native implementation
which was needed to achieve acceptable
performance.

I’m not sure there’s such a resource.
But really, all you need to know is:
it’s never collected, must call
dispose. You actually should do that
on desktop as well but if you don’t
its way more forgiving. Not so on
NETCF.

生来就爱笑 2024-07-13 20:39:44

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

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

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

A Form does not automatically Dispose all Controls created in its code, as it has no way to know it exists. To get the Form to Form to Dispose it automatically when it's Disposed, you need to add it to the Controls collection.

Now in your case that may not do anything. I can't tell if your example is contrived, or real world. If it's real-world, then the behavior is expected, as the Panel doesn't get collected when the variable goes out of scope (not sure it does on the desktop either). It becomes available for collection, but that simply means that on the next collection pass it will be swept. Unless you're causing a GC, then it's not going to be freed.

I'd highly recommend you take a look at the MSDN webcast on memory management in the CF. It provides a much more thorough explanation as to what's happening under the hood - far more than we could provide in an answer here.

定格我的天空 2024-07-13 20:39:44

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

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

  • 已分配 1MB 对象,

  • 应用程序移至后台,

  • 分配内存失败

  • 应用程序调用 GC.Collect。

Are you sure you have a memory leak? The .NET Compact Framework garbage collector works slightly differently to the one in the full .NET framework. From Steven Pratschner's blog:

A collection is initiated when either:

  • 1MB of objects have been allocated,

  • An application is moved to the background,

  • A failure to allocate memory occurs

  • An application calls GC.Collect.

鲜肉鲜肉永远不皱 2024-07-13 20:39:44

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

也是来自 Steven Pratschner。

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

希望这有帮助!

I think you need to dynamically remove the Button Click EventHandler too, as you can see from this blog :
http://blogs.msdn.com/stevenpr/archive/2007/03/08/finding-managed-memory-leaks-using-the-net-cf-remote-performance-monitor.aspx

It is from Steven Pratschner too.

By the way, the webcast mentioned above is linked here:
http://msevents.microsoft.com/cui/WebCastEventDetails.aspx?culture=en-US&EventID=1032318791&CountryCode=US

Hope this helps!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文