科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道编写对GC友好,又不泄漏的代码

编写对GC友好,又不泄漏的代码

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

1.使用更多生命周期短的、小的、不改变指向(immutable)的对象,编写清晰的代码。 出于懒惰也好,朴素的节俭意识也好,我们都习惯对一个变量重用再重用。但是.... Java的垃圾收集器喜欢短生命周期的对象。

作者:中国IT实验室 来源:中国IT实验室 2007年9月26日

关键字:

  • 评论
  • 分享微博
  • 分享邮件

在本页阅读全文(共2页)



 
    5.WeakReference/SoftReference 

   这是个平时不怎么会搭理,偶然知道了又觉得有用的Java特征。大家都知道Java里所有对象除int等基本类型外,都是Pass by Reference的指针,实例只要被一个对象连着,就不会被收集。
    而WeakReference就是真正意义上的C++指针,只是单纯的指向一个对象,而不会影响对象的引用计数。
    而SoftReference更特别,在内存足够时,对象会因为SoftReference的存在而不被收集,但内存不足时,对象就还是会被收集,怎么看都是做简单缓存的料子。代码如下: 



  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 不是有垃圾收集器了吗?怎么还泄漏啊,唬我啊??
   嗯,此泄漏非比泄漏。C/C++的泄漏,是对象已不可到达,而内存又没有回收,真正的内存黑洞。
   而Java的泄漏,则是因为各种原因,对象对应用已经无用,但一直被持有,一直可到达。
   总结原因无外乎几方面: 

    被生命周期极长的集合类不当持有,号称是Java内存泄漏的首因。
    这些集合类的生命周期通常极长,而且是一个辅助管理性质的对象,在一个业务事务运行完后,如果没有将某个业务对象主动的从中清除的话,这个集合就会吃越来越多内存,可以用WeakReference,如WeakHashMap,使得它持有的对象不增加对象的引用数。 
Scope定义不对,这个很简单了,方法的局部变量定义成类的变量,类的静态变量等。 
异常时没有加finally{}来释放某些资源,JDBC时代也是很普遍的事情。 
    另外一些我了解不深的原因,如:Swing里的Listener没有显式remove;内部类持有外部对象的隐式引用;Finalizers造成关联对象没有被及时清空等。 
内存泄漏的检测 

有不少工具辅助做这个事情的,如果手上一个工具也没有,可以用JDK自带的小工具: 

看看谁占满了Heap?
用jmap可以显示运行程序中对象的类型,个数与所占的大小
先用jps 找到进程号,然后jmap -histo pid 显示或 jmap -dump:file=heap_file_name pid 导出heap文件 
为什么这些对象仍然可以到达?
用jhat(Java Heap Analysis Tool) 分析刚才导出的heap文件。
先jhat heap_file_name,然后打开浏览器http://localhost:7000/ 浏览。 

查看本文来源

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章