锁定老帖子 主题:编写对GC友好,又不泄漏的代码
精华帖 (6) :: 良好帖 (1) :: 新手帖 (0) :: 隐藏帖 (11)
|
|
---|---|
作者 | 正文 |
发表时间:2007-06-19
作者:江南白衣,最新版链接:http://blog.csdn.net/calvinxiu/archive/2007/05/22/1621051.aspx,版权所有,转载请保留原文链接。 看到JavaOne2007上有篇《Garbage-Collection-Friendly Programming》的68页PPT,心想都2007了还谈这个基本问题,一定总结得很全面了才好意思站出来讲吧。 GC的基础概念见上篇:JDK5.0垃圾收集优化之--Don't Pause 1.使用更多生命周期短的、小的、不改变指向(immutable)的对象,编写清晰的代码。 出于懒惰也好,朴素的节俭意识也好,我们都习惯对一个变量重用再重用。但是....
所以有标题的呼吁,比如不要害怕为中间结果分配小对象。但编程习惯的改变也不是一朝一夕的事情。
2.将用完的对象设为NULL其实没什么作用。 貌似很酷的把对象主动设为Null 的"好习惯"其实没什么用,JIT Compiler会自动分析local变量的生命周期。
3.避免显式GC--System.gc()。 大家都知道System.gc()不好,full-gc浪费巨大,gc的时机把握不一定对等等,甚至有-XX:+DisableExplicitGC的JVM参数来禁止它。 哈哈,但我还不会用System.gc()呢,不怕不怕。真的不怕吗?
如果无可避免,用-Dsun.rmi.dgc.client.gcInterval=3600000 -Dsun.rmi.dgc.server.gcInterval=3600000 (单位为微妙) 增大大GC的间隔(原默认值为1分钟),-XX:+ExplicitGCInvokesConcurrent 让System.gc() 也CMS并发执行。
4.继续千夫所指的finalize() 大家也都知道finalize()不好,分配代价昂贵,释放代价更昂贵(要多走一个循环,而且他们死得慢,和他们相关联的对象也跟着死得慢了),又不确定能否被调用(JVM开始关闭时,就不会再进行垃圾收集),又不确定何时被调用(GC时间不定,即使system.gc()也只是提醒而不是强迫GC,又不确定以什么样的顺序调用,所以finalize不是C++的析构函数,也不像C++的析构函数。 我们都知道啊,所以我从来都没使用。都是在显式的维护那些外部资源,比如在finally{}里释放。
5.WeakReference/SoftReference 这是个平时不怎么会搭理,偶然知道了又觉得有用的Java特征。大家都知道Java里所有对象除int等基本类型外,都是Pass by Reference的指针,实例只要被一个对象连着,就不会被收集。 Foo foo = new Foo();
SoftReference sr= new SoftReference(foo); Foo bar = sr.get(); 如果foo已被垃圾收集,sr.get()会返回Null; 另外还有一个ReferenceQueue的机制,使得对象被回收时能获得通知,比finalize()完全不知道GC何时会执行要聪明的多。 ReferenceQueue rq = new ReferenceQueue();
ref = new WeakReference(foo, rq); WeakReference cleaned = rq.pool(); cleaned就是刚刚被GC掉的WeakReference。 6.内存泄漏 java 不是有垃圾收集器了吗?怎么还泄漏啊,唬我啊??
内存泄漏的检测 有不少工具辅助做这个事情的,如果手上一个工具也没有,可以用JDK自带的小工具:
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
浏览 3937 次