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

2022-03-22 15:15:48 +08:00
 soooulp

打开 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);
} 
821 次点击
所在节点    问与答
5 条回复
zhaofish
2022-03-22 15:26:55 +08:00
你是怎么看内存占用的? double click 之后 Application.Exit ,程序就退出了,怎么还有内存占用
soooulp
2022-03-22 15:36:46 +08:00
软件里面新建的 Form ,关闭了通过 form 显示的图片窗口,程序还未关哦
zhaofish
2022-03-22 16:48:18 +08:00
@soooulp 确认 img 对象是否被正确释放了。你这个写法也不是 C#推荐的写法,如果是继承了 IDisposable 接口的对象,应该使用 using 语句包裹。Forms.Application.Run(form)是不是阻塞式的,要等 form.Close 调用后才转到 img.Dispose ,而你在 doubleclick 里面是不是抛异常了,导致 img.Dispose 没有被调用。

是不是我落伍了,C#里面有 function(s, args)这种语句?不应该是 pic.DoubleClick += (sender, args) => ...这种写法吗?
soooulp
2022-03-22 17:15:04 +08:00
@zhaofish 嗯嗯,封装过啦,没有异常,估计是 img.Dispose 没执行,换成 form.ShowDialog();貌似内存也没变化
ysc3839
2022-03-22 21:07:45 +08:00
GC.Collect 是真的回收内存,而不是转移到虚拟内存吧?

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/842115

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX