我可能不了解该锥体或我做错了什么. 我对.NET中的内存管理有一些疑问.
May I do not understand the conecept or I do something wrong. I have some questions about the memory management in .NET.
想象一下情况:
Form1是大个子形式,因为MDI父级和一点FormChild被绑定为子级:
Form1 is the big man Form, as MDI-parent and a little FormChild, is bound as child:
public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void simpleButton1_Click(object sender, EventArgs e) { FormChild formChild = new FormChild(); formChild.MdiParent = this; formChild.Show(); } }现在孩子正在分配一点内存作为模拟:
Now the child is allocating a little bit memory as simulation:
public partial class FormChild : Form { private readonly List<byte[]> _list = new List<byte[]>(); public FormChild() { InitializeComponent(); } private void FormChild_Load(object sender, EventArgs e) { int i = 0; while (i < 100) { _list.Add(new byte[1024 * 1024 * 10]); i += 1; } } }现在,我正在使用内存探查器检查内存堆中发生了什么. 我看到,如果我单击按钮,则会分配内存.然后关闭FormChild,它调用Dispose().但是仍然分配内存.如果我再次单击,则会出现System.OutOfMemoryException.
Now, I'm inspecting with a memory profiler whats going on in the memory heap. I see, if i click on the button, the memory is allocated. Then I close the FormChild and it calls Dispose(). But the memory is still allocated. If I click again a System.OutOfMemoryException occures.
为什么GC等待释放托管内存? 还是这是我的设计错误?
Why is the GC waiting to free the managed memory? Or is this my mistake of design?
推荐答案它看起来像是一种计时问题,其中formChild的第一个实例仍然可以访问(即,不是垃圾),而第二个实例已创建.您不能两次容纳该_list.
It looks like some sort of timing problem, where the first instance of formChild is still reachable (ie not garbage) wen the second one is created. You can't accommodate that _list twice.
请注意,我关闭FormChild并调用Dispose()是关于资源和Window句柄的声明,而不是关于释放内存的声明.
Note that I close the FormChild and it calls Dispose() is a statement about resources and Window handles, not about freeing the memory.
尚不清楚您是否编写了自己的Dispose(),但在这种情况下(应该是特殊的情况),您应该这样做.
It is not clear if you wrote your own Dispose() but in this (rather special) case you should.
-
从FormChild.Designer.cs文件中剪切void Dispose(bool disposing)方法并将其移至FormChild.cs.
Cut the void Dispose(bool disposing) method from the FormChild.Designer.cs file and move it to FormChild.cs .
使用它释放巨大的内存块:
use it to release the huge memory block:
protected override void Dispose(bool disposing) { _list = null; // add this if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); }
请注意,这不是内存管理的常规"形式,但因为您的_list也很不正常,所以需要它.
Note that this is not a 'usual' form of memory management but it's needed because your _list is unusual too.
更多推荐
内存泄漏和处理
发布评论