Form.close()会释放内存吗?

5
我正在处理有许多表单打开和关闭操作的反馈应用程序。当我启动应用程序时,我注意到内存中的一些变化,它占用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();

请给我建议,如何减少内存使用。


调用垃圾回收器并不实际,因为垃圾回收器通常被推迟到释放内存是必要的时候。这样会提高性能。 - Willem Van Onsem
@doctor 我不确定你为什么要进行这么多编辑,但请注意每次编辑都会将问题推到首页,因此请仅限于必要的编辑。 - DavidG
3个回答

4
不,当你调用Form.Close()时,你只是告诉它关闭窗体。对象仍然驻留在内存中,如果你有对它的引用,它将一直存在,直到你持有该引用。
.NET具有自动垃圾回收机制,可以收集垃圾对象(你没有对它们的引用,也无法访问它们)。因此,当对象变成垃圾并且.NET垃圾回收器开始工作时,它们就会从内存中删除。你可以通过调用GC.Collect()来强制执行垃圾回收器。
更多关于GC的信息。

即使您调用了GC.Collect()方法,严格来说也不能保证垃圾回收器会真正进行回收... - Willem Van Onsem
1
是的,垃圾回收有许多方面。我只是试图简化它。@CommuSoft - Hamid Pourjam
那么在这种情况下,我该如何释放内存呢? - Hot Cool Stud
1
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - usr

4
它确实会影响您的UI对象,但不会自动处理您使用的变量。在这样的应用程序中,使用占用非托管资源很多但占用GC堆空间很少的大型对象时,垃圾回收器通常不会频繁运行以避免出现问题。你需要通过显式地释放对象来帮助它,以免让GC来处理任务。
可能需要等待相当长的时间才能开始运行,而在运行finalizers之前可能会积累大量的非托管内存使用,从而导致OOM崩溃,尽管目前离这个问题还很远。现在你只是运行比较"重"。
为FormClosed事件添加事件处理程序。你需要调用gfxScreenshot和bmpScreenshot对象上的Dispose()方法。那些HondaDb对象肯定也需要某种清理方式。
不要假设它会立即解决内存使用增加的问题,GC不愿意将地址空间立即释放回操作系统,而是保留它并假设您很可能很快需要它。适当的使用模式是在一段时间后稳定在合理的数量,然后突然下降并重新建立。一个锯齿形的图案。编写一个小单元测试,反复创建和销毁您的窗体对象,确保它执行截图和访问数据库等非微不足道的工作。现在您可以自信地知道没有出现失控泄漏问题了。

1

看一下这个MSDN线程。它是关于可释放的Windows,这应该释放由类的实例持有的所有资源。然后垃圾回收器应该做它的工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接