为了账号安全,请及时绑定邮箱和手机立即绑定

循环引用导致内存泄漏?

/ 猿问

循环引用导致内存泄漏?

慕桂英546537 2019-10-21 15:28:13

我试图减少Windows窗体应用程序中的内存泄漏。我现在正在查看包含几个嵌入式表单的表单。我担心的是,孩子的形式,在其构造,采取父窗体参考,并保持在一个私有成员字段。所以,在我看来,来的垃圾收集时间:


父具有对儿童形式的引用,通过控制集合(子形式被嵌入在那里)。子窗体未GC'd。


子形式具有与母体形式的引用,经由专用成员字段。父窗体不GC'd。


这是对垃圾收集器如何评估情况的准确理解吗?任何方式“证明”它用于测试目的?


查看完整描述

3 回答

?
撒科打诨

好问题!

不会,这两种形式都是(可以)GC的,因为GC不会直接在其他参考文献中查找参考文献。它仅查找所谓的“ Root”引用...包括堆栈上的引用变量(变量在堆栈上,实际对象当然在堆上),CPU寄存器中的引用变量以及类中的静态字段...

如果所有其他参考变量在通过上述过程找到的“根”参考对象之一的属性中被引用(或在由根对象中的参考引用的对象中被引用),则仅对其进行访问(和GC处理)等)。

因此,只有在“根”引用中其他位置引用了其中一种形式时,这两种形式才能从GC中安全使用。

只有我能想到的方法来“证明”的,(不使用记忆痕迹的实用程序)将创建这些形式对夫妇十万,在一个循环的方法中,然后,而在方法,看一下应用程序的内存占用,然后从方法退出,调用GC,并在接地再看看。


查看完整回答
反对 回复 2019-10-21
?
繁星coding

正如其他人已经说过的那样,GC在循环引用方面没有问题。我想补充一点,.NET中泄漏内存的常见位置是事件处理程序。如果您的表单中有一个附加到“活动”对象的事件处理程序,则该表单将被引用,并且该表单将不会被GC。


查看完整回答
反对 回复 2019-10-21
?
尚方宝剑之说

垃圾收集通过跟踪应用程序的根来工作。应用程序根目录是包含对托管堆上的对象(或为null)的引用的存储位置。在.NET中,根是

  1. 对全局对象的引用

  2. 对静态对象的引用

  3. 对静态字段的引用

  4. 堆栈上对本地对象的引用

  5. 堆栈上对传递给方法的对象参数的引用

  6. 对等待完成的对象的引用

  7. CPU寄存器中对托管堆上对象的引用

活动根列表由CLR维护。垃圾收集器通过查看托管堆上的对象并查看哪些对象仍可被应用程序访问(即可通过应用程序根访问)来工作。这样的对象被认为是扎根的。

现在假设您有一个父表单,其中包含对子表单的引用,而这些子表单也包含对父表单的引用。此外,假设应用程序不再包含对父表单或任何子表单的引用。然后,出于垃圾收集器的目的,这些受管对象不再植根,并且在下次发生垃圾收集时将被垃圾收集。


查看完整回答
反对 回复 2019-10-21

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信