【发布时间】:2021-10-16 16:05:43
【问题描述】:
我制作了一个每 30 毫秒绘制位图 (800x500) 的应用。并将它们显示在图片框中,并且绘制图像中的部分是对象。这个过程每次渲染使用50MB,我很担心。
这是渲染代码:
Public Function Draw() As Bitmap
Dim b as New Bitmap(RenderWidth * Me.Camera.Zoom, RenderHeight * me.camera.zoom)
Dim g = graphics.FromImage(b)
For each i in me.elements
Dim calculated as new point(i.location.x - me.camera.x, i.location.y - me.camera.x)
Dim resized as new bitmap(i.Image, New Size(i.Image.Width * i.Scale, i.Image.Height * i.Scale))
g.DrawImage(resized, caluculated)
Next
'camera zooming code
Dim oldSize as size = b.Size
Dim calculatedLoc = CalucLoc(oldSize, rendersize)
b = b.Clone(New Rectangle(caluclatedLoc, RenderSize), b.Pixelformat)
Return b
End Function
Function CalucLoc(bigSize, smallSize) as Point
Dim result as new size
Dim half_w1 = bigSize.Width / 2
Dim half_h1 = bigSize.Height / 2
Dim half_w2 = smallSize.Width / 2
Dim half_h2 = smallSize.Height / 2
Dim caluc_x = half_w1 - half_w2
Dim caluc_y = half_h1 - half_h2
result = New Point(caluc_x, caluc_y)
return result
End Function
元素类不做任何事情,它只是充当所有属性的容器。
【问题讨论】:
-
您在何时何地释放所有正在创建的位图?它们占用了内存,如果你一直占用它并且从不给予任何回报,那么你将在某个时候耗尽。当您创建一个新位图并将其分配给
b时,您似乎也在泄漏内存,然后几行之后将其丢弃以支持b = b.clone()的其他内容的副本。这意味着在 GC 运行之前,每次调用Draw()时,您都会暂时获得两个b的副本。 -
Bitmap实现了IDisposable,这很可能意味着它具有易于泄漏的非托管资源。你永远不应该使用Bitmap而不将它封闭在Using块中,或者确保在完成后直接调用Dispose(很可能通过在另一个对象的Dispose中调用Dispose实现IDisposable)。 -
这不仅仅是您正在创建的位图,还需要处理 Graphics 对象。只需使用
Using语句声明 Graphics 对象; 预先计算要渲染的位图区域,因此您无需循环构建新的位图,只需定义其大小即可。返回该 Bitmap 对象,因为您在 PictureBox 中显示它,所以添加[Your PictureBox].Image?.Dispose() [Your PictureBox].Image = Draw()。目前尚不清楚elements包含什么,为什么不将此集合传递给方法以及它引用的对象是否也需要被释放。 -
@Jimi 元素类中没有方法,只有
new方法,我会尝试dispose()方法 -
从来没有说过这样的话。
element是对象的集合(图像,来自您所显示的内容),因此如果您不重用它们,则需要在此集合引用的每个对象上调用Dispose():这不清楚,因为您没有'没有描述这些图像的用途和来源。现在重要的部分是:1) 使用Using语句声明 Graphics 对象,2) 在分配新 Bitmap 之前处理之前分配给 PictureBox 的 Bitmap,如下所述:[The PictureBox].Image?.Dispose() [The PictureBox].Image = Draw()3) Don '不要在循环中创建位图。
标签: vb.net memory system.drawing