Java会发生内存泄漏吗? - Achely's Blog

   JAVA会产生内存泄露吗?首先,答案是肯定的。Java虽然有垃圾回收器,但依然存在泄漏。
   Java内存泄漏跟C/C++内存泄漏的概念不一样:C/C++的内存泄漏是指Malloc了一些资源,{zh1}没有free掉,内存没有回收,这个是真正意义上的内存黑洞;而Java的泄漏则可能是别的原因,Java对象的存在对程序已经没有意义,但是对象在程序周期内一直存在,这个可能会导致Java的内存泄漏。
   总结原因,大概有下面几个方面:
  (1)Java的某个对象被一个生命周期很长的类不当持有,这个是Java内存泄漏最主要的原因,对象在某个Task中没有主动xx,其宿主在工作时会不断增加该对象的引用数,也就会吃掉更多的内存,从而导致内存泄漏;
(2)在Runtime Exception的时候,没有用finally{}来释放某些资源;
(3)变量范围的扩大,比如说一个方法的局部变量被定义成类的变量,这样导致变量的生命期变长,有可能导致泄漏(这个和{dy}点还是有点像的)。
   那么JAVA的垃圾回收机制(Gabage Collection)是怎么样的呢?垃圾收集机制是指jvm用于释放那些不再使用的对象所占用的内存。java语言并不要求jvm有gc,也没有规定gc如何工作。不过常用的jvm都有gc,而且大多数gc都使用类似的算法管理内存和执行收集操作。垃圾收集的目的在于xx不再使用的对象。gc通过确定对象是否被活动对象引用来确定是否收集该对象。两种常用的方法是引用计数和对象引用遍历。
(1)引用计数:引用计数存储对特定对象的所有引用数,也就是说,当应用程序创建引用时,jvm必须适当增减引用数。当某对象的引用数为0时,便可以进行垃圾收集。
(2)对象引用遍历:早期的jvm使用引用计数,现在大多数jvm采用对象引用遍历。对象引用遍历从一组对象开始,沿着整个对象图上的每条链接,递归确定可到达(reachable)的对象。如果某对象不能从这些根对象的一个(至少一个)到达,则将它作为垃圾收集。在对象遍历阶段,gc必须记住哪些对象可以到达,以便删除不可到达的对象,这称为标记(marking)对象。
然后,gc要删除不可到达的对象。删除时,有些gc只是简单的扫描堆栈,删除未标记的对象,并释放它们的内存以生成新的对象,这叫做xx(sweeping)。这种方法的问题在于内存会分成好多小段,而它们不足以用于新的对象,但是组合起来却很大。因此,许多gc可以重新组织内存中的对象,并进行压缩(compact),形成可利用的空间。
为此,gc需要停止其他的活动活动。这种方法意味着所有与应用程序相关的工作停止,只有gc运行。结果,在响应期间增减了许多混杂请求。另外,更复杂的 gc不断增加或同时运行以减少或者xx应用程序的中断。有的gc使用单线程完成这项工作,有的则采用多线程以增加效率。
   参考原文:http://allenshao.javaeye.com/blog/624393
   参考原文:http://www.javaeye.com/topic/244277
   发表于 @ 2010年05月20日 21:17:00 | 评论( loading... ) | 编辑| 举报| 收藏 旧一篇:社会点滴 | 新一篇:error 与 Exception区别 查看{zx1}精华文章 请访问博客首页相关文章

/文章来自:
/引用通告地址:
/Tags:
郑重声明:资讯 【Java会发生内存泄漏吗? - Achely's Blog】由 发布,版权归原作者及其所在单位,其原创性以及文中陈述文字和内容未经(企业库qiyeku.com)证实,请读者仅作参考,并请自行核实相关内容。若本文有侵犯到您的版权, 请你提供相关证明及申请并与我们联系(qiyeku # qq.com)或【在线投诉】,我们审核后将会尽快处理。
—— 相关资讯 ——