Winform关闭窗口后如何清理内存?

打开Winform窗口后,内存一直增加,关闭窗口后,内存不会还原,使用Dispose();没有效果

比如第一段代码中使用Winform显示图片

另外找到.NET API中,GC.Collect();SetProcessWorkingSetSize函数,会降低内存显示,实际上是转移到虚拟内存中,效果非常不好

是否有好的办法关闭form窗口后,清理内存的呢

var Forms = forms.System.Windows.Forms;
var form = new Forms.Form;
form.StartPosition = Forms.FormStartPosition.Manual;
form.FormBorderStyle = Forms.FormBorderStyle.None;
form.TopMost = true;
form.ControlBox = false;
form.ShowInTaskbar = false;
form.Margin = new Forms.Padding(0);
form.Padding = new Forms.Padding(1);
form.MinimumSize = new Size(10, 10);
form.Size = new Size(10, 10);
form.Location = new Point(100, 100);
form.AutoSize = true;
form.GetType().GetProperty("DoubleBuffered",
    host.flags(clr.System.Reflection.BindingFlags.NonPublic,
    clr.System.Reflection.BindingFlags.Instance))
    .SetValue(form, true);
form.BackColor = drawing.System.Drawing.SystemColors.HotTrack;

var pic = new Forms.PictureBox;
pic.Name = 'pic';
pic.SizeMode = Forms.PictureBoxSizeMode.Zoom;
pic.Size = new Size(450, 500);
pic.BackColor = drawing.System.Drawing.SystemColors.Control;
pic.Location = new Point(0, 0);
pic.Image = img;

form.Controls.Add(pic);
var autoSize = form.Size;
var t = (form.ClientSize.Width - pic.Width - form.Padding.Horizontal);
autoSize.Width -= t;
autoSize.Height -= t;
form.AutoSize = false;
form.Size = autoSize;
pic.Dock = Forms.DockStyle.Fill;

var form_shown = 
form.Shown.connect(
function (sender, args) {
    form.TopMost = true;
    form.Activate();
});

var pic_doubleClick = 
pic.DoubleClick.connect(
function (sender, args) {
    form.Dispose();
    pic.Dispose();
    Forms.Application.Exit();
    form.Close(); 
});

Forms.Application.Run(form);
img.Dispose();

使用SetProcessWorkingSetSize

form.Close(); 
FlushMemory();
function FlushMemory()
{
    System.GC.Collect();
    System.GC.WaitForPendingFinalizers();
    if (System.Environment.OSVersion.Platform == System.PlatformID.Win32NT)
        SetProcessWorkingSetSize(System.Diagnostics.Process.GetCurrentProcess().Handle, -1, -1);
} 
阅读 3.5k
1 个回答

一般注意这么两点:

  • 一般打开窗口,窗口内的子组件都会有订阅的事件,这种情况下要确保窗口关闭后,把相关事件取消订阅
  • 打开的窗口关闭后,要保证这个窗口引用的变量要释放掉,否则窗口不能释放。原因一般都是这个窗口引用的变量,外面也在用,不能释放这个变量,这样窗口也就释放不了
  • 如果用到非托管资源需要自己释放,GC 不会帮忙

总的来说要多检查你的代码中的对象是否被多个地方引用,这可能是导致的不能被释放的原因

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进