Java Virtual Machine Garbage Collection浅析

来源:互联网 发布:淘宝关联账户能开店吗 编辑:程序博客网 时间:2024/06/10 06:00

  在软件开发过程中,Java开发者往往不用关心JVM内存的申请和回收,因为JVM会统一管理对像内存空间的申请和回收。而c/c++开发中,开发者可以自已去管理内存.这中间有管理好的,有管理不好的。比如一个新手写的基于C/C++的server上线后,可能因为内存分配问题,经常宕机,而一个基于Java的Server上线后,也会碰到反应慢,打不开,OutOfMemory等情况。

     虽然JVM GC会统一管理对象的回收,但它也不是无所不能的,它需要大家去了解它,帮助它更好地管理我们server端的内存。

     系统在运行的过程中会不断产生新的对象,这些新的对象会占用一定的内存空间。内存空间是有限的,但对象会不断的产生,所以JVM会定期清理那些被废弃的对象(通过根搜索算法,GCRoot无法达到的对象)。这时候就会产生几个问题:

    定期:什么时间? a.并发,一边工作,一边清理 b.暂停所有工作,清理废弃对象。

    从最早期的JVM垃圾回收机制来看,JVM并没有采取a方式,而是采用了b方式。最早期的Serial垃圾回收器的工作方式是"Stop the World". 为什么JVM没有采用a方式呢?暂不讨论。 "Stop the world"就意味着JVM需要停下手中的工作,来整理一下内存空间。这个时候Server就有了一个停顿时间,如果一个Server运行了100s,GC一次用了2s,那么它的吞吐量可以看成98%。

    下面展示了GC所占时间,系统吞吐量带来的影响。

   

 

      是不是GC所占时间越短,系统的吞吐量越高?right! 首先感谢那些默默为提高JVM GC效率作出杰出贡献者的大神们!

      回忆一下,常见的垃圾回收算法:

      废弃对象:简单来讲就是没有被GCRoot直接或间接引用到的对象。 

      标记清除: 标记废弃的对象,直接清除。 会造成内存碎片。

      标记整理: 在标记清除算法的基础上,最后需要整理一下内存空间。消除碎片

      分代复制:把空间分成几块,把有用的对象copy到另一块,然后整块清除原来的那一块。频繁对象的复制,耗时。

      只有这些是不够的,大神们又发现了部分对象在垃圾回收的过程中,它们的命很硬,每次都是走走过场。

下图中我们可以发现,大部分对象的生命都很短,很早就被废弃了。



      最后大神们为每个对象加上一个年龄,每经历一次GC年龄就加1.超过一定的年龄的对象群众不需要频繁的去做GC.  这个时候就发现了两个群体。一个群体是生命比较短暂,另一个群体生命比较长。即年青代和老年代。

      年青代每次GC存活的对象比较少,分代复制算法比较适合它们。因为它们需要复制很少。 老年代每次GC存活的对象比较多,比较适合标记整理算法。所以这个时候存在不同年代的垃圾收集器。但凡事无绝对的,还需要具体情况具体分析。  

    

        同时随着硬件的提高,大部分服务器已经是多CPU,这个时候就可以考虑使用基于并行的垃圾收集器。


Reference:

http://www.oracle.com/technetwork/java/javase/gc-tuning-6-140523.html

0 0
原创粉丝点击