【第三帖】C# 如何销毁子窗口对象,关于垃圾回收机制,望大家交流

zhangshuqiang123 2010-11-18 10:55:05
问题是这样引起的,我在A窗口声明了一个B窗口对象(全局的),然后A窗口中按下一个按钮就实例化这个对象,并show出来,问题来了,我的B窗体中有几个public static类型的变量(因为B窗体还有它的子窗体也会用到这些数据,所以就用了public static的),用来存放从文本文件读取过来的数据(很大)所以占用了相当大一块内存,当我关闭窗体的时候,窗体Dispose的。但是发现内存还是占用那么多的,后来百度之后发现这个public static的是会一直存在的,知道程序退出之后才销毁,这个很郁闷了,我如果打开关闭多操作几次,这个内存占用就直线攀升,一下子就操作1G。越来越慢,这样肯定是不行的,所以来寻求解决方案。

ps:1.我的文本文件大概50MB 是不是读到内存中去之后也会占用50MB的内存。为什么我读一次就消耗100+MB的内存呢?
2.我如果将B对象的声明放在A窗体Button单击事件里面(也就是局部变量),关闭窗口之后貌似会减少内存占用。
3.网上找了大家的解答方法
       /// <summary>
/// 在占用大量内存的窗体关闭时执行,释放内存
/// </summary>
public static void FlushMemory()
{
GC.Collect();
GC.WaitForPendingFinalizers();
if (Environment.OSVersion.Platform == PlatformID.Win32NT)
{
SetProcessWorkingSetSize(System.Diagnostics.Process.GetCurrentProcess().Handle, -1, -1);
}
}
用了这个方法之后,貌似内存占用在关闭的时候也会减少,但是虚拟内存并没有减少,而且一致增加,然后每次关闭B窗口的时候内存占用会减少,但是再次打开,会马上上升到原来的哪个水平,跟(虚拟内存)一样高,相当与累加了前几次的量
4.我想问一下,是不是可以在B窗体关闭的时候 将A中B对象 null一下就可以消耗B对象。B对象没了,是不是原来B对象中的东西都会没有,就不会那么占用内存空间了呀?
5.网上找了很多资料,了解了一些.net GC方面的东西,发现还是不够用啊,望大家指导,QQ联系我:869996152 ,MSN:mr.zhangshuqiang@hotmail.com
...全文
422 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
zhangshuqiang123 2010-11-18
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 mohugomohu 的回复:]

static程序开始运行的时候就分配资源了,你关闭窗体的时候把static设为null
[/Quote] 这样做了,可是没用
mohugomohu 2010-11-18
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 mohugomohu 的回复:]

一般没必要手动调用GC.Collect();系统会自动回收的,因为每回收一次都会使资源的年龄增长,有时候会更慢
[/Quote]
因为GC.Collect();是针对整个托管堆的
mohugomohu 2010-11-18
  • 打赏
  • 举报
回复
一般没必要手动调用GC.Collect();系统会自动回收的,因为每回收一次都会使资源的年龄增长,有时候会更慢
mohugomohu 2010-11-18
  • 打赏
  • 举报
回复
static程序开始运行的时候就分配资源了,你关闭窗体的时候把static设为null
zhangshuqiang123 2010-11-18
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 pcqpzq 的回复:]

窗口用完也要Dispose(),尤其是非模式窗口
[/Quote]哈哈,如何操作
zhangshuqiang123 2010-11-18
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 pcqpzq 的回复:]

此外,打开文件和流等操作,记得打开完了将流Close(),用完Dispose()
[/Quote]
关闭的窗口的时候是不是自动Dispose的呀?

文件读写操作完成之后我都会close();

看看我的Dispose有没有问题
   /// <summary>
/// 清理所有正在使用的资源。
/// </summary>
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
FlushMemory();
}

/// <summary>
/// 在占用大量内存的窗体关闭时执行,释放内存
/// </summary>
public static void FlushMemory()
{
GC.Collect();
GC.WaitForPendingFinalizers();
if (Environment.OSVersion.Platform == PlatformID.Win32NT)
{
SetProcessWorkingSetSize(System.Diagnostics.Process.GetCurrentProcess().Handle, -1, -1);
}
}

private void MainForm_FormClosed(object sender, FormClosedEventArgs e)
{
GC.Collect();
}


谢谢你的回答哦!
zhangshuqiang123 2010-11-18
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 pcqpzq 的回复:]

你在关闭B后,要把B中的Static变量设成null就可以了
[/Quote]
设置成null之后,还是没有效果,虚拟内存使用还是没有释放,然后每次关闭B窗口的时候内存占用会减少,但是再次打开,会马上上升到原来的哪个水平,跟(虚拟内存)一样高,相当与累加了前几次的量
达不溜来多多 2010-11-18
  • 打赏
  • 举报
回复
Dispose()
pcqpzq 2010-11-18
  • 打赏
  • 举报
回复
窗口用完也要Dispose(),尤其是非模式窗口
pcqpzq 2010-11-18
  • 打赏
  • 举报
回复
此外,打开文件和流等操作,记得打开完了将流Close(),用完Dispose()
pcqpzq 2010-11-18
  • 打赏
  • 举报
回复
你在关闭B后,要把B中的Static变量设成null就可以了

111,129

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Creator Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧