C# 是否在Form.close()上释放了内存?
我正在开发反馈应用程序,该应用程序有很多表单打开和关闭操作。我注意到我的应用程序中的内存变化很少,当我启动我的应用程序时,它需要25 MB的内存。用户给出的每个反馈都会增加3MB的内存使用量。在每个窗体上,当它从一个跳转到另一个或有任何关闭操作时,我都使用了这个.close()。记忆增加的可能原因是什么 我是否需要手动调用垃圾收集器,因为每个人都说这不是一个好的做法 在本例中,我使用的是双监视器场景,在该场景中,应用程序在每500毫秒后拍摄辅助屏幕的快照,并将其显示在主屏幕上。为此,我使用的代码如下所示:C# 是否在Form.close()上释放了内存?,c#,.net,winforms,garbage-collection,C#,.net,Winforms,Garbage Collection,我正在开发反馈应用程序,该应用程序有很多表单打开和关闭操作。我注意到我的应用程序中的内存变化很少,当我启动我的应用程序时,它需要25 MB的内存。用户给出的每个反馈都会增加3MB的内存使用量。在每个窗体上,当它从一个跳转到另一个或有任何关闭操作时,我都使用了这个.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();
建议我如何节省内存。不,当您调用
Form.Close()
时,您只是告诉我要关闭表单。对象仍在内存中,如果您有对它的引用,它将一直存在,直到您持有该引用为止
.NET具有自动垃圾收集机制,可收集垃圾对象(您没有对它们的引用,因此无法访问它们)。因此,当对象成为垃圾时,会将其从内存中删除,.NET垃圾收集器会启动它。您可以通过调用GC.Collect()
强制执行垃圾收集器
更多关于的信息请看一看。这是关于可释放窗口的,它应该释放类实例所持有的所有ressource。然后垃圾收集器应该完成它的工作。它完成了,但只是你的UI对象。对于您使用的变量,它不是自动的。在这样一个应用程序中,使用占用很少GC堆空间但占用大量非托管资源的大对象,垃圾收集器通常不会经常运行以避免麻烦。您必须帮助并显式地处理对象,这样就不会让GC来处理作业 它可能需要太长时间才能开始运行,在它运行终结器之前,您可能会积累大量非托管内存使用。使用OOM可能会使您的程序崩溃,尽管您离这个问题还很远。现在你只是在跑“重” 为FormClosed事件添加事件处理程序。您需要对gfxScreenshot和bmpScreenshot对象调用Dispose()方法。当然,这些对象也需要某种清理
不要认为这会立即解决内存使用增量问题,GC并不急于将地址空间释放回操作系统。而是假设你很快就会需要它。正确的使用模式是,它在一段时间后稳定在一个合理的数量上,然后突然下降并恢复。锯齿形图案。编写一个小单元测试,反复调用创建和销毁表单对象,确保它完成截图和访问数据库等非琐碎工作。现在,您可以放心地知道您没有失控泄漏问题。调用垃圾收集器是不现实的,因为垃圾收集器通常会推迟到需要释放内存时。这样就提高了性能。@博士,我不知道你为什么要做这么多编辑,但要知道每次编辑都会把问题推到头版,所以请将编辑限制在必要的部分。即使你调用
GC.Collect()
,严格来说,也不能保证GC会收集……是的,垃圾收集有很多方面。我只是想让它变得简单@Commusofthen在这种情况下,我如何释放内存。@HotCoolStud调用Dispose,就像您在任何其他包含非托管资源且IDisposable的对象上调用Dispose一样。