Dim*_*ima 5 .net memory events memory-leaks event-handling
在这里和那里,人们一直在谈论由于未发布的事件监听器而发生的内存泄漏.我认为这是一个非常重要的问题.非常严肃而且非常重要......如果确实存在的话.
我曾尝试自己来重现问题,但我所有的努力都失败了:我不能让我的应用程序泄漏内存:(虽然这听起来不错,我还是很担心:也许我失去了一些东西.
那么也许有人可以提供一个非常简单的源代码示例,导致内存泄漏?
我创建了一个小型VB.NET应用程序作为演示:它包含一个Windows窗体和一个类.
Windows窗体:它有一个集合对象(名为"c")和两个按钮:一个用于向集合添加10个项目,另一个用于清除集合:
Public Class Form1
Dim c As New Collection
Private Sub btnAddItem_Click(sender As System.Object, e As System.EventArgs) Handles btnAddItem.Click
For i As Integer = 1 To 10
Dim m As New MyType
c.Add(m)
Next
Me.Text = c.Count
End Sub
Private Sub btnClear_Click(sender As System.Object, e As System.EventArgs) Handles btnClear.Click
For Each item As MyType In c
item.Dispose()
Next
c.Clear()
Me.Text = c.Count
End Sub
End Class
Run Code Online (Sandbox Code Playgroud)
MyType类:它有很大的m_Image对象,这个对象很大,所以你可以看到你的内存真正被MyType实例占用了:)
Imports System.Drawing
Public Class MyType
Implements IDisposable
Private m_Image As Bitmap
Public Sub New()
AddHandler Application.Idle, AddressOf Application_Idle
m_Image = New Bitmap(1024, 1024)
End Sub
Private Sub Application_Idle(sender As Object, e As EventArgs)
End Sub
#Region "IDisposable Support"
Private disposedValue As Boolean
Protected Overridable Sub Dispose(disposing As Boolean)
If Not Me.disposedValue Then
If disposing Then
m_Image.Dispose()
End If
End If
Me.disposedValue = True
End Sub
Public Sub Dispose() Implements IDisposable.Dispose
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
#End Region
End Class
Run Code Online (Sandbox Code Playgroud)
Jar*_*Par 12
这是一个非常直截了当的例子
class MyType
{
public static event EventHandler ExampleEvent;
public MyType()
{
ExampleEvent += (sender, e) => OnExampleEvent();
}
private void OnExampleEvent() { }
}
Run Code Online (Sandbox Code Playgroud)
任何实例MyType将订阅该ExampleEvent事件.此事件未附加到任何特定对象,因此它永远不会留下内存.这将MyType在应用程序的持续时间内保存内存中的所有实例.
编辑
正如在评论中所要求的那样,该MyType实例在不再使用后很长一段时间内停留在内存中
class Program
{
static void Main(string[] args)
{
WeakReference weakRef = new WeakReference(new MyType());
for (var i = 0; i < 10; i++)
{
GC.Collect();
GC.WaitForPendingFinalizers();
}
Console.WriteLine("Still Alive: {0}", weakRef.IsAlive);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2302 次 |
| 最近记录: |