java之内存泄漏

     内存泄漏的问题也是老生常谈的问题。C++由于内存的分配和回收都是由程序员自己管理的,coding的时候小心些,出现内存泄漏的几率就会很小。而java由于使用了GC,由GC自动去回收无用的内存,内存的管理似乎变得很简单。但是,如果不知道GC的工作原理,一旦出现内存泄漏的问题,就十分头痛了;即使知道了GC的工作原理,解决内存泄漏也是一件繁琐的工作。当然,了解GC的基本工作原理,对解决内存泄漏的问题自然是只有好处没有坏处。本文并不是介绍GC的工作原理,而是笔者在实际工作中解决内存泄漏问题的一点心得,希望对大家会有所帮助。

     市面上有许多中jvm的实现,每种jvm几乎都有自己的GC算法。但不管GC的算法如何,它的工作目的只有一个,就是要回收内存中不再使用的对象,释放内存。通常,GC会去检查内存中那些不再被引用的对象,然后标记这些对象,最后销毁这些对象。由于GC是由一个专门的线程来运行的,回收对象的时候也很消耗资源,所以,我们一般不知道什么时候GC会去回收内存。但这不是重点,重点是我们必须知道什么样的对象才是GC认为可以回收的对象,也就是说,什么对象才算是“不再被引用的对象”。关于这一点,网上的参考文献往往会指出,GC从“root”即根节点开始查找,只要能从这个“root”节点到达的对象,都是可用的对象,换句话说,如果一个对象的引用者是在以“root”为根的树上,这个对象就是可用的,那么,只要使这个对象脱离这棵树,即令对象的在那棵树上的引用者referrer=null,那么这个对象就可被回收。但很少有文献指出,这个“root”到底是什么?哪些节点一定会在“root”这棵树上?如果我们清楚了这个“root”的实际含义,问题就会迎刃而解了。

    其实这些“root”并不复杂。简单起见,就拿一个应用程序为例。假设一个应用程序有一个主线程,多个副线程。每个线程都会有一个入口,也就是每个线程都有一个主类,即含有pulic void main(String[] args)和pubic void run()的类,这个类中的字段,方法就是可能的“root”所在。只要一个线程在运行,主类中的字段,静态或者非静态的,就是“root”,同样,如果一个方法在运行,比如run()是个无限循环,这个方法中的变量,也成为了“root”。只要能从这些“root”出发,达到某个对象,这个对象就是无法被回收的。因此,简而言之,我们可以把“root”理解为一个线程。

    理解了这一点,解决内存泄漏的问题就不难了。“工欲善其事,必先利其器”。出现了内存泄漏,如果靠查看源码,那是事倍功半的法子。有一个好的工具来帮助我们查找问题的根源,那就事半功倍。java中关于内存调试的工具也蛮多的,borland公司的optimizer,bea公司jrockit中自带的一款工具等等。quest公司的JProbe也是很好的一个工具,关于这个工具介绍的网上资料也有一些,就不在赘述了。

         以下是Bea的关于内存泄漏的文章,有一定的参考价值:

         原文:

    http://dev2dev.bea.com/pub/a/2005/06/memory_leaks.html

   中文地址:
   http://www.matrix.org.cn/resource/article/43/43639_Memory_Leaks.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值