Chinaunix首页 | 论坛 | 博客
  • 博客访问: 591058
  • 博文数量: 718
  • 博客积分: 4000
  • 博客等级: 上校
  • 技术积分: 4960
  • 用 户 组: 普通用户
  • 注册时间: 2008-10-17 13:24
文章分类

全部博文(718)

文章存档

2011年(1)

2008年(717)

我的朋友

分类:

2008-10-17 13:28:02

    1.使用更多生命周期短的、小的、不改变指向(immutable)的对象,编写清晰的代码。 

    出于懒惰也好,朴素的节俭意识也好,我们都习惯对一个变量重用再重用。但是.... 

    的垃圾收集器喜欢短生命周期的对象,对象如果在新生代内,在垃圾收集发生前就死掉了,垃圾收集器就什么都不用做了。 
现代JVM构建一个新对象只需要10个本地CPU指令,并不弱于C/。 (但垃圾收集没有压缩算法时会稍慢,更频繁的New对象也导致更频繁的GC)。 
大对象的分配效率更低,而且对非压缩算法的垃圾收集器,更容易造成碎片。 
对象重用增加了代码的复杂度,降低了可读性。 
   所以有标题的呼吁,比如不要害怕为中间结果分配小对象。但编程习惯的改变也不是一朝一夕的事情。 


    2.将用完的对象设为NULL其实没什么作用。 

    貌似很酷的把对象主动设为Null 的"好习惯"其实没什么用,JIT Compiler会自动分析local变量的生命周期。
    只有一个例外情况,就是String[1024] foo 这种赤裸裸的数组,你需要主动的foo[100]=null释放第100号元素,所以最好还是直接用ArrayList这些标准库算了。 

 

    3.避免显式GC--System.gc()。 

    大家都知道System.gc()不好,full-gc浪费巨大,gc的时机把握不一定对等等,甚至有-XX:+DisableExplicitGC的JVM参数来禁止它。 

    哈哈,但我还不会用System.gc()呢,不怕不怕。真的不怕吗? 

先用FindBugs 查一下所用到的全部第三方类库吧... 
至少RMI 就会老实不客气的执行System.gc()来实现分布式GC算法。但我也不会用RMI啊。那EJB呢,EJB可是建在RMI上的.... 
    如果无可避免,用-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++的析构函数。 

   我们都知道啊,所以我从来都没使用。都是在显式的维护那些外部资源,比如在finally{}里释放。

[1]  

【责编:Youping】

--------------------next---------------------

阅读(283) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~