Form.close() 上是否释放了内存?

Hot*_*tud 5 .net c# garbage-collection winforms

我正在开发反馈应用程序,其中有很多表单打开和关闭操作。当我启动应用程序时,我注意到应用程序中的内存变化很少,需要 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;
}
Run Code Online (Sandbox Code Playgroud)

为了在打开其他表单时关闭表单,我使用下面的代码

formOpen.show();
formClose.Close();
Run Code Online (Sandbox Code Playgroud)

建议我如何节省内存使用。

Han*_*ant 4

确实如此,但只是你的 UI 对象。对于您使用的变量来说,它不是自动的。在这样的应用程序中,使用占用很少 GC 堆空间但占用大量非托管资源的大对象,垃圾收集器通常运行频率不足以让您摆脱麻烦。您必须帮助并明确地处置对象,这样您就不会让 GC 来处理这项工作。

它可能需要很长时间才能开始运行,您可以在运行终结器之前积累大量非托管内存使用量。尽管您距离该问题还很远,但 OOM 可能会导致您的程序崩溃。现在你只是在“重度”跑步。

为 FormClosed 事件添加事件处理程序。您需要对gfxScreenshotbmpScreenshot对象调用 Dispose() 方法。当然,那些HondaDb对象也需要某种清理。

不要假设会立即解决内存使用增量问题,GC 并不急于将地址空间释放回操作系统。保留它,并假设您可能很快就会需要它。正确的使用模式是一段时间后稳定在合理的数量,然后突然下降并恢复。锯齿状图案。编写一个小单元测试,反复调用创建和销毁表单对象,确保它完成截取屏幕截图和访问数据库等重要工作。现在您可以放心地知道您不存在失控泄漏问题。