GDI+移动线内存泄漏
我尝试使用 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
因此,上面的代码会在线条移动时导致内存泄漏。我认为原因是在幕后创建了非托管位图来绘制未发布的表单,因为在托管端它只是一个指针。
如果我在绘制函数的开头
Dim intAlloc As Integer = Me.Width * Me.Height * 16
GC.AddMemoryPressure(intAlloc)
和函数的末尾添加以下代码,我调用
GC.RemoveMemoryPressure(intAlloc)
内存利用率会增加一点并缩小一点,但永远不会失去控制。 AddMemoryPressure 和RemoveMemoryPressure 似乎提醒GC 它需要运行。有没有更好的方法来做到这一点或者这是正确的?上面的代码只是为了示例目的而进行的简化,以找到我在具有多条移动线的较大组件中遇到的问题的根源。这也是计算放置在 AddMemoryPressure 中的正确值的最佳方法吗?
I have tried to do this both with GDI+/Invalidate and by using a Line Shape Control. In both cases the memory spirals out of control. To demonstrate, create a windows form application with a timer object which is set to 100ms and enabled and use the following code:
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
So the code above causes a memory leak as the line moves. I think the reason is that there are unmanaged bitmaps created behind the scenes to paint the form which are not being released because on the managed side it is just a pointer.
If I add the following code at the start of the paint function
Dim intAlloc As Integer = Me.Width * Me.Height * 16
GC.AddMemoryPressure(intAlloc)
and at the end of the function I call
GC.RemoveMemoryPressure(intAlloc)
The memory utilization grows a little and shrinks a little but never grows out of control. The AddMemoryPressure and RemoveMemoryPressure seems to alert the GC that it needs to run. Is there a better way to do this or is this correct? The code above is just a simplification for example purposes to get to the root of a problem I have in a larger component with several moving lines. Also is this the best way to calculate the proper value to place in AddMemoryPressure?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论