我尝试使用GDI + / Invalidate和使用线形控件来做到这一点。在这两种情况下,记忆螺旋失控。要演示,请创建一个带有计时器对象的Windows窗体应用程序,该对象设置为100毫秒并启用并使用以下代码:
Public Class Form1
Private Y As Integer
Private intDirection As Integer = 1
Private Sub timTest_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles timTest.Tick
Me.Invalidate()
End Sub
Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
Dim g As Graphics = Me.CreateGraphics
Dim myPen As New Pen(Color.Black)
myPen.Width = 1
g.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
g.DrawLine(myPen, 10, 10, 200, Y)
Y += intDirection
If Y > Me.Height - 20 Then intDirection = -1
If Y < 0 Then intDirection = 1
g.Dispose()
myPen.Dispose()
End Sub
End Class
因此,上面的代码会在行移动时导致内存泄漏。我认为原因是在幕后创建了非托管位图来绘制未被释放的表单,因为在托管端它只是一个指针。
如果我在paint函数的开头添加以下代码
Dim intAlloc As Integer = Me.Width * Me.Height * 16
GC.AddMemoryPressure(intAlloc)
并在函数结束时调用
GC.RemoveMemoryPressure(intAlloc)
内存利用率略有增长,缩小了一点但从未失控。 AddMemoryPressure和RemoveMemoryPressure似乎提醒GC它需要运行。有没有更好的方法来做到这一点或这是正确的?上面的代码只是一个简化,例如目的是为了找到我在一个带有几条移动线的较大组件中遇到的问题的根源。这也是计算放入AddMemoryPressure的正确值的最佳方法吗?