日期:2014-05-20  浏览次数:20792 次

【讨论】C#性能、代码优化问题。
只有183分了。
在做Winform的时候当一个窗体的控件过多的时候,或者new的对象多的时候窗体show以后会占用很多内存。从几KB到10MB不等。
这个窗体关闭时内存不会及时释放,而是等待被回收。 如果手动调用垃圾回收的话,调用次数过多过于频繁反而又会增加占用的内存。导致一个程序如果长时间运行会使内存增长至百兆甚至更多。用C#写过服务的应该有体会。

现在我的做法就是
1、全局变量尽量给null值,用的时候在new。但是用完以后怎么释放呢。。等待垃圾回收?
2、窗体关闭的时候手动调用GC.Collect强制进行垃圾回收。 (很多人不推荐这样做。)

不知道大家在做程序的时候怎样进行优化,减少内存的占用及时释放垃圾资源。





------解决方案--------------------
Winform确实很垃圾,
.NET象Java一样,是为Web程序而生的,
ASP.NET中,一般是不需要考虑内存释放的问题的,
GC能完美搞定,
而且一般ASP.NET运行于服务器版操作系统,
服务器版操作系统的内存管理比桌面版强得多~
------解决方案--------------------
其实.NET里面关于内存释放的问题已经说了很多很多,真的很多了。


我个人认为只要理解下面两点点即可:
1、理解垃圾回收机制,什么对象是垃圾?什么不是?什么是根?什么时候对象被放到了哪个代上?大对象怎么分配怎么释放?
2、如果你不想要这个对象了,那么就让它变成垃圾吧,其他的就交给GC,别去控制GC,你的智商一般都不会比微软的高,所以你的算法肯定没有他的好,为什么不能控制GC(当然也不是绝对的)自己好好想想吧。

做好上面两点,其他的不用过分操心,内存的增长是在所难免的,托管堆是建立在这样一个神话之上的:内存是无限大的。我们的内存当然不是无限大,托管堆是顺序排列的,程序开始运行,运行时开始分配托管堆,此时的托管堆是0字节,G0-G1-G2都是挨在一起的,大对象堆也是空的,呃~~~貌似扯远了。

做好上面两点,其他的就由GC来完成吧,当然对于非托管资源当然有自己的释放机制,这里不再描述,相信也是被说烂的概念了。
------解决方案--------------------
就算是手动调用了GC 并不会立即释放内存!

至于说占用内存大的一说,我们开发的一个项目,主窗体显示出来后,内存占用一直在40M左右!

和# viena# (wien 维也纳)相反的是,我基本做的都是WinForm应用,他说:".NET象Java一样,是为Web程序而生的."这点我不大赞同,.NET的WinForm程序依然可以做的强大且稳定。

WinForm程序跑起来要加载诸如System.Dll,System.WinForm.Dll,System.Drawing.DLL等等.NET自带的和自己的类库,这些类库一旦加载就一直存内存中,而在WebForm中只是在服务器端存在这种现象,所以,在WinForm中内存占用小不到哪里去。

至于给LZ的建议,没什么好说的,以下是一些个人看法,不对请指出:

1.彻底不用的对象就Dispose()掉,但是频繁的new 一个对象出来造成的性能损失和长期占有内存的资源耗费,视具体情况而定,比如频繁的对文件执行读写操作,不会要每次读取或写入完成后都Dispose掉吧!

2.尽量少使用全局变量即可(窗体上的控件也属于全局变量,多了也造成内存耗费).

3.使用系统资源的对象尽快Dispose掉.

4.使用IO的对象尽快Dispose掉。

不足的请大家补充。谢谢!
------解决方案--------------------
探讨
只有183分了。
在做Winform的时候当一个窗体的控件过多的时候,或者new的对象多的时候窗体show以后会占用很多内存。从几KB到10MB不等。
这个窗体关闭时内存不会及时释放,而是等待被回收。 如果手动调用垃圾回收的话,调用次数过多过于频繁反而又会增加占用的内存。导致一个程序如果长时间运行会使内存增长至百兆甚至更多。用C#写过服务的应该有体会。

现在我的做法就是
1、全局变量尽量给null值,用的时候在new。但是用完以后怎么释放呢。。等待垃圾回收?
2、窗体关闭的时候手动调用GC.Collect强制进行垃圾回收。 (很多人不推荐这样做。)

不知道大家在做程序的时候怎样进行优化,减少内存的占用及时释放垃圾资源。

------解决方案--------------------
win2003 企业版以上的都是支持4G以上内存的