引用存储在Session变量中的对象的变量是否由GC收集?

时间:2011-04-13 13:07:59

标签: c# memory-management garbage-collection

我并不熟悉垃圾收集的工作原理以及导致内存泄漏的原因。但我现在关注它并希望编写更高效的代码。因此,我正在开发的项目是一个Asp.Net Web应用程序,当一个Session在global.asax中启动时会创建一个自定义DataCriteria实例,然后存储在Session变量中。此自定义DataCriteria是我们用于与CRUD方法的数据库通信的内容。

第一个问题是,假设我们有一个Person类,并且在这个Person类中有一个DataCriteria字段,它被设置为DataCriteria的Session变量实例。由于Person的实例持有对DataCriteria实例的引用,该实例在Session结束之前不会被处理掉,因此可以收集Person的实例。或者,在该会议结束之前,不会处置每个人的实例。

第二个问题更为笼统,但问题相同。基本上我想知道在引用DataCriteria的Session变量实例的方法中声明的变量是否能够被GC收集?或者它会在会议结束之前保持不变?

我感谢你提供给我的所有建议。如果您知道任何有关理解垃圾收集和避免内存泄漏的良好读数,我也很乐意听到它们。

2 个答案:

答案 0 :(得分:2)

对象持有的引用不会影响其对垃圾回收的可用性。但是,反之则不然。例如,假设实例A有一个包含实例B的字段。只要没有其他内容引用它,A就会可用于垃圾收集,即使B是静态的或“长期存在”。但是,在A可用于垃圾收集之前,B将无法用于垃圾收集至少

事情变得有点奇怪的地方是参考不太明显。例如,当C订阅由D公开的事件时,实例C将引用实例C.这意味着,如果D是长期存在的,则在D之前C将不可用于垃圾收集,除非它取消订阅该事件。通过事件和其他代理持有的引用实际上是.NET应用程序中大多数“内存”泄漏的原因。 (正确地说,这些并不是真正的内存泄漏,因为实际上没有清理实际对象实例未使用的内存。)

答案 1 :(得分:1)

对象引用构成有向图 - 对象A引用对象B.在收集A之前,B不能。

Session只是引用内容的另一个对象 - 在这种情况下,对象A引用了对象B.

所以在你的情况下,只是因为Person引用存储在Session中的东西并不意味着Person会一直存在,直到Session消失。除非Session引用了你的Person,否则它们的生命周期没有关联。

现在您需要注意的是DataCriteria引用的其他内容。如果它包含数据库连接或其他对象,它们将在会话中存在。