假设我们有一个Windows窗体,其中有一个名为SimpleButton1的按钮.以下代码导致无法控制的内存使用量.我做错了什么?
我的理解是,在for循环的每次迭代中,GC都会清理任何TestClass对象,并且会处理任何相关事件,因为任何事件都没有处理程序
Public Class Form1
Private Sub SimpleButton1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SimpleButton1.Click
For i = 1 To 1000000
Dim test1 As New TestClass
Next
End Sub
End Class
Public Class TestClass
Private Event TestEvent(ByVal sender As Object)
End Class
Run Code Online (Sandbox Code Playgroud)
请注意,我已经尝试实现IDisposable并在For循环的每次迭代结束时调用test1.Dispose(),但我怀疑我没有处置正确的资源.
*答案:代码中没有问题,它按预期运行.问题是我在调试模式下运行它,并且创建的开销导致大量内存使用.见下面的讨论.
你在这里没有展示的,我怀疑的问题是,在你的TestClass中,你有事件TestEvent,而你可能正在向TestEvent添加处理程序,你可能不会删除它们.通过不删除它们,您告诉GC不要收集TestClass或处理程序的类.
正如您所示,此代码不会泄漏.垃圾收集器最终会处理您创建的类.
但是,如果你有一个Observable类和一个Observer类,Observer将调用Observable.Event += Observer.EventHandler; 通过这样做,Observable现在有一个返回Observer的引用.如果你不打电话Observable.Event -= Observer.EventHandler,那么这个参考就会存在.
当您认为没有人对Observer有引用时会出现问题,但Observable的生命周期更长.尽管Observable具有对Observer的引用,但是除非它清除所有处理程序(this.Event = null),否则没有代码知道删除引用.
实际上,这是一个内存泄漏!
有几种方法可以解决这个问题:
| 归档时间: |
|
| 查看次数: |
265 次 |
| 最近记录: |