.NETCF 中的内存泄漏 - 创建动态控件?
我在 .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。
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:
GC Heap:
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这里有一些附加信息解释了这种行为。
根据 Ilya Tumanov 的说法:
Some additional information here that explains this behaviour.
According to Ilya Tumanov:
表单不会自动释放在其代码中创建的所有控件,因为它无法知道它的存在。 要让 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.
你确定有内存泄漏吗? .NET Compact Framework 垃圾收集器的工作方式与完整 .NET 框架中的垃圾收集器略有不同。 来自 Steven Pratschner 的博客:
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:
我认为您也需要动态删除 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!