社区
C#
帖子详情
进来谈谈.net 对象占用内存立即释放
jxnetinfo
2006-05-15 10:15:56
1.如何立即释放一个对象占用的内存,我做过个测试 对象实现了IDispose接口
重写了Dispose方法
Dispose(true);
GC.SuppressFinalize(this);
但执行对象 Dispose方法时,该对象的状态还是继续保留,那就是对象还没从内存中消失,有什么方
法 可以立即砌底的释放对象的资源
2.有没有程序中的必要所有对象都继承IDispose接口
...全文
1845
30
打赏
收藏
进来谈谈.net 对象占用内存立即释放
1.如何立即释放一个对象占用的内存,我做过个测试 对象实现了IDispose接口 重写了Dispose方法 Dispose(true); GC.SuppressFinalize(this); 但执行对象 Dispose方法时,该对象的状态还是继续保留,那就是对象还没从内存中消失,有什么方 法 可以立即砌底的释放对象的资源 2.有没有程序中的必要所有对象都继承IDispose接口
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
30 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
shrinerain
2007-02-07
打赏
举报
回复
对于Image对象,如果是放在using里面,或者用完及时进行了Dispose
不会每次30M内存上升.
确认代码不存在环引用以及交叉引用.
shrinerain
2007-02-07
打赏
举报
回复
我是专职QA, Performance Testing是我工作内容之一.
实际上,在服务器端,很多时候IO的影响远大于内存.
shrinerain
2007-02-07
打赏
举报
回复
此言差亦……
你做过相册么?相册中包含的图片从文件中读来,更换图片的时候,你如何把得到的Image对象释放掉呢?.net提供GC.Collect是有用处的。并非空穴来风,我以前一个程序因为涉及到读取硬盘上不确定位置的一个图片文件,更换Picture的Image的时候,不调用GC.Collect,内存每次30M的速度镖升。加了就好了。
在必要的时候还是要自己调用释放。因为就算你的内存用了接近1G,.net可能也不会自动替你做一次释放的。这个我尝试过,虚拟内存最高用到过960M。
---------------------------------------------------------
Image对象是非托管资源对象,并不是托管对象.
另外,内存使用量小不代表系统性能高.你需要对整个系统进行CPU,内存,IO三个方面的监测,才能得出性能数据. 我想你也许没有考虑GC.Collect时系统的CPU和IO使用情况.
newskycity
2007-02-07
打赏
举报
回复
有理!
兔子-顾问
2007-02-07
打赏
举报
回复
shrinerain(圣影雨) ( ) 信誉:100 Blog 2007-2-6 19:48:31 得分: 0
永远不要强制进行垃圾回收,这样只会更加降低性能.
此言差亦……
你做过相册么?相册中包含的图片从文件中读来,更换图片的时候,你如何把得到的Image对象释放掉呢?.net提供GC.Collect是有用处的。并非空穴来风,我以前一个程序因为涉及到读取硬盘上不确定位置的一个图片文件,更换Picture的Image的时候,不调用GC.Collect,内存每次30M的速度镖升。加了就好了。
在必要的时候还是要自己调用释放。因为就算你的内存用了接近1G,.net可能也不会自动替你做一次释放的。这个我尝试过,虚拟内存最高用到过960M。
「已注销」
2007-02-07
打赏
举报
回复
up
halve
2007-02-07
打赏
举报
回复
好文章,收藏下
xiaoliangwh
2007-02-07
打赏
举报
回复
帮顶 !
shrinerain
2007-02-07
打赏
举报
回复
那么StringBuilder这样不提供Dispose的如何释放?
------------------------------------------------
StringBuilder是托管对象,这个你不用担心了,放心让CLR自己处理吧 :)
兔子-顾问
2007-02-07
打赏
举报
回复
或许吧。可能真如你所说的。托管资源都不要手工调用GC.Collect。可能之前做那个测试例子的时候是不够了解,没注意。我用下面代码验证了shrinerain(圣影雨)话的正确性。
OpenFileDialog dlg = new OpenFileDialog();
if (dlg.ShowDialog() == DialogResult.OK)
{
Image img = Image.FromFile(dlg.FileName);
if (this.BackgroundImage != null)
{
this.BackgroundImage.Dispose();
}
this.BackgroundImage = new Bitmap(img);
img.Dispose();
}
这个是可以了。不会无限增长。之前没注意,原来FromFile是不关闭文件的。学习了。
那么StringBuilder这样不提供Dispose的如何释放?
兔子-顾问
2007-02-07
打赏
举报
回复
晕。看来真的和你说的一样。打开图片后。.net竟然不知道自己关闭文件。这个期间,我只要图片,怎么断开图片和文件的关联?莫非要绘制一次?
shrinerain
2007-02-07
打赏
举报
回复
这里要说的是,托管对象是什么。非托管对象是什么。文件是系统资源,打开后需要关闭,载入导内存之后,文件操作就结束了。哪里来的非托管对象。Bitmap是System.Drawing的对象。这个是非托管的么?
----------------------------------------------------------
一切本地资源,比如文件,网络等等,都是"非托管资源",并不是说写在C#里的东西,就是"托管对象". 所谓"托管对象",是指由CLR分配在托管堆上面的类实例,而你说的本地图片,并不属于这一类.
打开一个文件,载入内存,然后并不是这个文件就"关闭"了,而是仍然"打开"的,这个文件的句柄是被当前程序独占的,其他程序并不能使用.
除非你显式的进行了"CloseHandle"的工作,在C#中就是调用Dispose()或者Close()等方法.文件才真正被"释放".
用C++来讲,就是要分清楚"指针"与"指针指向的对象"之间的关系. 举个不合适的例子,Bitmap你当作一个指针,那张图片,就是指针指向的对象. Bitmap是托管对象,但那张图片不是. C++我们常说的"野指针",就是释放了指向的对象,但是没有释放指针本身.
如果言辞不妥,请见谅... : )
shrinerain
2007-02-07
打赏
举报
回复
呵呵...
不好意思,我没有任何"发怒"的意思...
我之所以说"永远不要强制进行垃圾回收,这样只会更加降低性能." 是因为在我的楼上,已经有很多人解释了Dispose等是针对非托管资源. 所以我的话是以他们为前提的.
所以我的意思完整的是"对于托管对象,永远不要强制进行垃圾回收,只会更加降低性能."
而对于你说的Image,对于本地非托管资源,微软正是推荐采用GC.Collect()进行垃圾收集.
当然,世界上任何事情都不是绝对的,但是一般我们说话,都不会多于的加上一句"从概率上来讲...",是吧,:)
事实上,微软的确是完全不推荐用GC.Collect();进行托管对象的强制收集,只所以保留,毕竟因为还有非托管资源,而且有些很少的特殊场合,涉及到对象生存期,垃圾收集器工作不一定完全按我们所想.比如在多线程领域,垃圾收集器并不是工作的特别完美.
兔子-顾问
2007-02-07
打赏
举报
回复
GC.Collect是有参数的,你可以指定的释放哪个带里的内容,并非每次都要调用没有参数的重载。并且可以吧这个方法不要频繁调用。比如你重置界面的时候,这个时候执行一次是比较合理的。如果频繁的调用。这样可能的确会影响性能。
兔子-顾问
2007-02-07
打赏
举报
回复
/*
Image对象是非托管资源对象,并不是托管对象.
另外,内存使用量小不代表系统性能高.你需要对整个系统进行CPU,内存,IO三个方面的监测,才能得出性能数据. 我想你也许没有考虑GC.Collect时系统的CPU和IO使用情况.
*/
这里要说的是,托管对象是什么。非托管对象是什么。文件是系统资源,打开后需要关闭,载入导内存之后,文件操作就结束了。哪里来的非托管对象。Bitmap是System.Drawing的对象。这个是非托管的么?
//实际上,在服务器端,很多时候IO的影响远大于内存.
难道服务器的内存是无限的?io要考虑,那是数据库访问方面的,和我所说的是一回事么?
对于您的职业我不是很关心,但是钻牛角尖和使用比较绝对的言词往往会引出争论。
兔子-顾问
2007-02-07
打赏
举报
回复
楼上的哥们息怒。
诶。算了。是我不对。不该引用你的名字,更不该直接的说你的观点错误。
但我所说的是windows application程序,相册。并且没有任何的环、交叉之类的,简简单单一个图片框,更换图片为400+ * 600+的图而已。我所说的只是个个别的例子,只是认为你上面所说的“永远不要强制进行垃圾回收,这样只会更加降低性能.”太绝对了。
担心你的话会误导他人。
我只是举例说明gc.collect的作用是有必要自己手动调用的。我坚持我的观点,否则如果真的如你所说,永远不要用,那你该直接致电微软总部,要求取消这个没有封装好,让我们能看到,能调用的静态方法。因为它没用。
greenery
2007-02-06
打赏
举报
回复
up
真相重于对错
2007-02-06
打赏
举报
回复
用.net 就不要去考虑性能,只管用最好的机器招呼
shrinerain
2007-02-06
打赏
举报
回复
永远不要强制进行垃圾回收,这样只会更加降低性能.
Ivony
2006-05-15
打赏
举报
回复
Dispose和Finallize都是相对于非托管资源而言的,托管资源不能手动释放。可以尝试GC.Collect。
任何类包含了非托管资源,就必须实现析构函数确保非托管资源能被GC释放。同时应实现IDispose接口用于手动释放非托管资源。
加载更多回复(9)
.NET
内存
占用
大原因
本文主要分析了
.NET
中
内存
占用
较大的原因。包括垃圾回收机制相关因素,如分代回收策略和回收开销;托管堆特性,如
对象
大小和布局;资源未及时
释放
,如非托管资源泄漏和缓存问题;以及第三方库和框架的影响,如
内存
管理方式差异和版本Bug等。
net
内存
回收和
对象
的销毁 net
内存
手动
释放
本文探讨了C++的手动
内存
管理和现代语言如Java、C#的自动垃圾回收机制。C#中,
对象
销毁可通过实现IDisposable接口的Dispose()方法或垃圾回收器自动完成,析构函数用于
释放
非托管资源。这种灵活性使得C#在资源管理上既高效又易于维护。
C#计算
对象
占用
内存
大小(
.net
)
本文探讨了C#中
对象
占用
内存
的计算,重点关注字段个数、类型和布局对
内存
大小的影响。通过LayoutKind的三种模式(Auto、Sequential、Explicit)分析了不同布局下
对象
占用
的空间,并使用windbg进行了验证,揭示了CLR的字段优化策略。
.NET
/C# 如何获取当前进程的 CPU 和
内存
占用
?如何获取全局 CPU 和
内存
占用
?
本文介绍了如何通过
.NET
的PerformanceCounter类获取全局及当前进程的CPU和
内存
占用
情况,详细解释了性能计数器的使用,包括创建计数器实例、读取值等,并提到了不同
内存
指标的含义。
DotNetGuide
内存
优化:减少
.NET
应用的
内存
占用
.NET
应用的
内存
优化至关重要,尤其在高并发场景下。本文详细介绍了
.NET
内存
管理的基础知识、常见问题及12种实战优化策略,涵盖资源
释放
、大
对象
处理、字符串优化等内容,并提供
内存
泄漏检测与修复方法。通过实际案例展示优化效果,帮助开发者降低
内存
占用
40%-60%,提升GC效率。
C#
111,129
社区成员
642,540
社区内容
发帖
与我相关
我的任务
C#
.NET技术 C#
复制链接
扫一扫
分享
社区描述
.NET技术 C#
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
让您成为最强悍的C#开发者
试试用AI创作助手写篇文章吧
+ 用AI写文章