新建的项目,有窗口FORM1,新建一个窗口FORM2
FORM1中有一个按钮,点击后执行如下代码:for (int i = 0; i < 100; i++)
{
Form2 f = new Form2();
f.Show();
f = null;
}打开100个FORM2窗口FORM2窗口中有如下代码:private void Form2_Load(object sender, EventArgs e)
{
Thread th = new Thread(run);
th.Start();
}private void run()
{
Thread.Sleep(10000);
this.Close();
this.Dispose();
}窗口Form2在显示10秒后关闭。执行程序后,占用内存10056K,打开100个窗口后占用12928K,关闭100个窗口后占用内存12172K。
尝试使用GC.Collect();强制释放内存,未生效。
当多次点击按钮后,内存占用会越来越高,请问这种情况应该怎么解决?
FORM1中有一个按钮,点击后执行如下代码:for (int i = 0; i < 100; i++)
{
Form2 f = new Form2();
f.Show();
f = null;
}打开100个FORM2窗口FORM2窗口中有如下代码:private void Form2_Load(object sender, EventArgs e)
{
Thread th = new Thread(run);
th.Start();
}private void run()
{
Thread.Sleep(10000);
this.Close();
this.Dispose();
}窗口Form2在显示10秒后关闭。执行程序后,占用内存10056K,打开100个窗口后占用12928K,关闭100个窗口后占用内存12172K。
尝试使用GC.Collect();强制释放内存,未生效。
当多次点击按钮后,内存占用会越来越高,请问这种情况应该怎么解决?
{
}
在就是用Gc了
我怎么感觉你那线程怪怪的。
private void CloseForm()
{
if (this.InvokeRequired)
{
this.BeginInvoke(new DelegateCloseForm(CloseForm));
}
else
{
this.Close();
this.Dispose();
}
}
private void run()
{
Thread.Sleep(10000);
CloseForm();
}
*****************************************************************************
欢迎使用CSDN论坛专用阅读器 : CSDN Reader(附全部源代码) http://feiyun0112.cnblogs.com/
{
WaitCallback wcb = delegate { run(); };
ThreadPool.QueueUserWorkItem(wcb);
}
GC.Collect();
调用这个方法是会释放内存的。还有就是垃圾回收1代 满的时候CLR关闭的时候占用内存10056K,打开100个窗口后占用12928K,关闭100个窗口后占用内存12172K。
这个并不能说明你关闭后,就应该还是10056K内存。因为还有其他资源消耗的内存,比如线程,线程在你关闭够不是把上销毁的。
而且你这里获得的内存也一定准确
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;namespace WindowsApplication53
{
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
} private void Form2_Load(object sender, EventArgs e)
{
Thread th = new Thread(run);
th.Start();
} delegate void d(); private void run()
{
Thread.Sleep(1000);
this.Invoke(new d(this.Close));
GC.Collect(); // 放这里
}
}
}
{
Thread.Sleep(1000);
this.Invoke(new MethodInvoker(delegate(){this.Close}));
}
异常退出?我倒,我试验过了,没有任何的错误,而且按钮按了好几次,内存几乎没有增长
异常退出是你其它地方有问题吧把form1也贴上,贴全Form1 :using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;namespace WindowsApplication53
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
} private void button1_Click(object sender, EventArgs e)
{
for (int i = 0; i < 100; i++)
{
Form2 f = new Form2();
f.Show();
}
}
}
}Form2 :
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;namespace WindowsApplication53
{
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
} private void Form2_Load(object sender, EventArgs e)
{
Thread th = new Thread(run);
th.Start();
} delegate void d(); private void run()
{
Thread.Sleep(1000);
this.Invoke(new d(this.Close));
GC.Collect(); // 放这里
}
}
}
启用后占用10052K,开100个窗口后是14240K,关闭后是占用12908K。
因为何时去调用GC.Collect();放在哪里很难确定,
要找到一个地方能确定form已经释放而且线程也已经结束的地方调用GC.Collect();但你这个例子里很难找到这种地方
因为我另外要做一个软件,在后台打开一个窗口,窗口中有WEB控件,这个WEB控件登录后进行一系列操作,然后关闭窗口,每一分钟大约打开两个窗口,都是在隐藏执行的。
现在最麻烦的就是内存问题,大约两个小时左右,就可以把1G的内存吃掉,在进程中多处执行GC.Collect();都不管用。
所以我简化问题,直接开两个最简单的窗口来实验,但看来大家都很少关注过这个问题。
{
WaitCallback wcb = delegate { run(); };
ThreadPool.QueueUserWorkItem(wcb);
} private void run()
{
try
{
Thread.Sleep(10000);
CloseHandler handler = closeModule;
Invoke(handler);
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
} private void closeModule()
{
Close();
Dispose();
GC.Collect();
}
这个代码可以回收,但是就如上面所言,不可能完全回收。
{
Form2 f = new Form2();
f.Show();
f = null;
}——————————————————————————————
Form2 f;
for (int i = 0; i < 100; i++)
{
f = new Form2();
f.Show();
}
{
Thread th = new Thread(run);
th.Start();
th.join();
this.Close();
}private void run()
{
Thread.Sleep(10000);
}
GC.Collect();
GC.WaitForPendingFinalizers();一般.net程序在最小化后会把内存释放,不知道是什么原因
100个线程的状态是已死亡,但内存没有释放,而是从终结列表移到了终结可达列表。
所以只有在第2次垃圾回收时才能被回收。垃圾回收是在调用GC.Collect或者0代对象满本执行,完成会会清理终结可达列表。但是之前的线程可能从0代提升到1代,1代没有满时,GC是不会回收的。在点N此按钮后,你多次调用GC.Collect,在用WINDBG查看Threads会发现已经没有死亡还不释放内存的线程了。LZ的情况是存在,启动10M,100个窗体13M,全关闭并垃圾回收后12M,确实不知道为什么。
但是还有另外个情况你可以看下,你吧窗体最小化,在打开,你发现内存只有3M了。
然后我又进行了大搞20次操作,基本内存都保持在10M左右。可见应该不会有内存泄漏的问题,垃圾回收(自动)肯定是起作用了。你可以用CLRProfiler看看内存,这个我看不懂 - -!