存储器泄漏。使创造动态的控制?
-
03-07-2019 - |
题
我有一个问题与存储器泄漏中的一个。净CF应用程序。
使用 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。收集()也不会导致小组正在清理。
2.使用。净CF2.0sp1Windows CE4.2设备。
解决方案
此处的一些其他信息可以解释此行为。
NETCF上的所有UI都是 故意从GC范围中删除 永远不会收集。这种行为 与桌面有所不同 在NETCF V3.5中更改(除非运行 在兼容模式下。)
因为管理的UI,它是如此不同 NETCF上的类完全是 与桌面不同。他们很瘦 本机实现的包装器 这是实现可接受的 性能
我不确定是否有这样的资源。 但实际上,您需要知道的是: 它永远不会收集,必须打电话 处置。你真的应该这样做 在桌面上也是如此,但如果你不这样做 它的方式更宽容。不久 NETCF。
其他提示
表单不会自动处理在其代码中创建的所有控件,因为它无法知道它存在。要使表单在表单处理时自动处理它,您需要将其添加到Controls集合中。
现在你的情况可能没有做任何事情。我不知道你的例子是人为的,还是现实世界。如果它是真实的,那么行为是预期的,因为当变量超出范围时不会收集Panel(不确定它是否也在桌面上)。它可用于收集,但这仅仅意味着在下一个收集过程中它将被扫描。除非你造成GC,否则它不会被释放。
我强烈建议你看一下关于CF内存管理的MSDN网络广播。它提供了一个更彻底的解释,说明了幕后发生的事情 - 远远超过我们在这里给出的答案。
你确定你有一个内存泄漏?。净契约框架的垃圾收集工作的方式略有不同的一个完整的。净框架。从 史蒂芬*Pratschner的博客:
一个收集是发起当:
1MB的对象已经分配,
一个应用程序移动的背景,
一个失败分配存储器发生
应用程序调GC。收集。
我认为您还需要动态删除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培养=的en-US&安培;事件ID = 1032318791&安培; COUNTRYCODE = US
希望这有帮助!