我正在研究反馈应用程序,它有很多形式的开放和关闭操作。当我启动应用程序需要25 MB时,我发现应用程序中的内存更改几乎没有变化。每个反馈用户给它增加3 MB的内存使用量。在每个表单上我使用this.close()当它从一个跳转到另一个或者有任何关闭操作。什么可能是内存增加的原因。
我是否需要手动调用垃圾收集器,因为每个人都说它不是很好的做法。
在此我正在使用双监视器场景,其中应用程序在每500毫秒后拍摄辅助屏幕的快照并在主屏幕上显示。为此,我使用下面显示的代码:
public EntryForm()
{
sc = Screen.AllScreens;
dbDms = new HondaDb(UtilityFunctions.getServerConnection());
db = new HondaDb(UtilityFunctions.getClientConnection());
bmpScreenshot = new Bitmap(sc[1].Bounds.Width,
sc[1].Bounds.Height,
PixelFormat.Format32bppArgb);
Create a graphics object from the bitmap.
gfxScreenshot = Graphics.FromImage(bmpScreenshot);
Timer timerClientScreen = new Timer();
timerClientScreen.Interval = 500;
timerClientScreen.Enabled = false;
timerClientScreen.Start();
timerClientScreen.Tick += new EventHandler(timer_TickClient);
}
void timer_TickClient(object sender, EventArgs e)
{
// Take the screenshot from the upper left corner to the right bottom corner.
gfxScreenshot.CopyFromScreen(sc[1].Bounds.X, sc[1].Bounds.Y,
0, 0, sc[1].Bounds.Size, CopyPixelOperation.SourceCopy);
// Save the screenshot to the specified path that the user has chosen.
pictureBoxClient.Image = bmpScreenshot;
}
关于其他人打开的表格,我正在使用下面的代码
formOpen.show();
formClose.Close();
建议我如何节省内存使用量。
答案 0 :(得分:4)
不,当您致电Form.Close()
时,您只是在告诉我要关闭表单。对象仍然存在于内存中,如果你有一个对它的引用,它将存在,直到你持有该引用。
.NET具有自动垃圾收集机制,它收集垃圾对象(您没有对它们的引用,也无法访问它们)。因此,当对象变为垃圾并且.NET垃圾收集器启动它时,它们将从内存中删除。您可以通过调用GC.Collect()
强制执行垃圾收集器。
有关GC
的更多信息答案 1 :(得分:4)
确实如此,但只是你的UI对象。对于您使用的变量,它不是自动的。在像这样的应用程序中,使用占用很少GC堆空间但是有大量非托管资源的大对象,垃圾收集器通常不会经常运行以使您免于麻烦。您必须提供帮助并显式处理这些对象,这样您就不会将其留给GC来处理这项工作。
它可能需要很长时间才能开始运行,你可以在运行终结器之前构建大量非托管内存使用量。使用OOM可能会使您的程序崩溃,尽管您仍然非常远离该问题。现在你只是在运行“沉重”。
为FormClosed事件添加事件处理程序。您需要在 gfxScreenshot 和 bmpScreenshot 对象上调用Dispose()方法。当然,那些 HondaDb 对象也需要进行某种清理。
不假设将立即解决内存使用量增量,GC不急于将地址空间释放回操作系统。保持它而不是假设你可能很快就会需要它。正确的使用模式是在一段时间后以合理的数量稳定,然后突然下降并重建。锯齿形图案。编写一个小单元测试,调用创建并重复销毁表单对象,确保它执行截取屏幕截图和访问dbase的重要工作。现在你可以放心地知道你没有一个失控的泄漏问题。
答案 2 :(得分:1)
看看这个MSDN Thread。它是关于一次性Windows的,它应该释放一个类实例所拥有的所有资源。然后垃圾收集器应该这样做。