zoukankan      html  css  js  c++  java
  • 深入理解java:1.3. 垃圾收集

    Java垃圾收集(Garbage Collection,GC)

    某一个时点,一个对象如果有一个以上的引用(Rreference)指向它,那么该对象就为活着的(Live),

    否则死亡(Dead),视为垃圾,可被垃圾回收器回收再利用。

    垃圾回收操作需要消耗CPU、线程、时间等资源,所以容易理解的是垃圾回收操作不是实时的发生(对象死亡后不会马上释放),

    当内存消耗完或者是达到某一个指标(Threshold,使用内存占总内存的比列)时,触发垃圾回收操作。

    GC需要完成的三件事情:

         哪些内存需要回收?

                --如何判断对象已死?用 根搜索算法

                这个算法的基本思路就是通过一系列的名为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链(Reference Chain)。

                当一个对象到GC Roots没有任何引用链相连时,则证明此对象是不可用的。

                在Java语言里,可作为GC Roots的对象包括下面几种:

                    虚拟机栈(栈帧中的本地变量表)中的引用的对象

                    方法区中的类静态属性引用的对象。

                    方法区中的常量引用的对象。

                    本地方法栈中JNI(即一般说的Native方法)的引用的对象

        什么时候回收?

                当内存消耗完或者是达到某一个阀值(Threshold,使用内存占总内存的比列)时,触发垃圾回收操作。阀值可通过JVM参数配置。

        如何回收?

        GC机制的基本算法是 分代收集,

        当新生代的Eden区满的时候,执行Minor GC,也叫 Young GC。使用了复制算法。

        当老年代内存不足时,将执行Major GC,也叫 Full GC。使用了标记-清除算法 或 标记-整理算法。

    在GC机制中,起重要作用的是垃圾收集器,垃圾收集器是GC的具体实现。如下图,

      

    新生代收集器:(都是使用 停止复制算法

    • Serial收集器:使用停止复制算法,使用一个线程进行GC,串行,其它工作线程暂停。使用-XX:+UseSerialGC可以使用Serial+Serial Old模式运行进行内存回收(这也是虚拟机在Client模式下运行的默认值)
    • ParNew收集器:使用停止复制算法,Serial收集器的多线程版,用多个线程进行GC,并行,其它工作线程暂停,关注缩短垃圾收集时间。使用-XX:+UseParNewGC开关来控制使用ParNew+Serial Old收集器组合收集内存;使用-XX:ParallelGCThreads来设置执行内存回收的线程数。
    • Parallel Scavenge 收集器:使用停止复制算法,关注CPU吞吐量。即运行用户代码的时间/总时间,比如:JVM运行100分钟,其中运行用户代码99分钟,垃 圾收集1分钟,则吞吐量是99%,这种收集器能最高效率的利用CPU适合运行后台运算(关注缩短垃圾收集时间的收集器,如CMS,等待时间很少,所以适 合用户交互,提高用户体验)。使用-XX:+UseParallelGC开关控制使用Parallel Scavenge+Serial Old收集器组合回收垃圾(这也是在Server模式下的默认值);使用-XX:GCTimeRatio来设置用户执行时间占总时间的比例,默认99,即1%的时间用来进行垃圾回收。使用-XX:MaxGCPauseMillis设置GC的最大停顿时间(这个参数只对Parallel Scavenge有效),用开关参数-XX:+UseAdaptiveSizePolicy可以进行动态控制,如自动调整Eden/Survivor比例,老年代对象年龄,新生代大小等,这个参数在ParNew下没有。

    老年代收集器:

      • Serial Old收集器:单线程收集器,串行,使用标记整理(整理的方法是Sweep(清理)和Compact(压缩),清理是将废弃的对象干掉,只留幸存的对象,压缩是将移动对象,将空间填满保证内存分为2块,一块全是对象,一块空闲)算法,使用单线程进行GC,其它工作线程暂停(注意,在老年代中进行标记整理算法清理,也需要暂停其它线程),在JDK1.5之前,Serial Old收集器与ParallelScavenge搭配使用。
      • Parallel Old收集器:老年代收集器,多线程,并行,多线程机制与Parallel Scavenge差不错,使用标记整理(与Serial Old不同,这里的整理是Summary(汇总)和Compact(压缩),汇总的意思就是将幸存的对象复制到预先准备好的区域,而不是像Sweep(清理)那样清理废弃的对象)算法,在Parallel Old执行时,仍然需要暂停其它线程。Parallel Old在多核计算中很有用。Parallel Old出现后(JDK 1.6),与Parallel Scavenge配合有很好的效果,充分体现Parallel Scavenge收集器吞吐量优先的效果。使用-XX:+UseParallelOldGC开关控制使用Parallel Scavenge +Parallel Old组合收集器进行收集。
      • CMS(Concurrent Mark Sweep)收集器:老年代收集器,致力于获取最短回收停顿时间(即缩短垃圾回收的时间),使用标记清除算法,多线程,优点是并发收集用户线程可以和GC线程同时工作),停顿小。使用-XX:+UseConcMarkSweepGC进行ParNew+CMS+Serial Old进行内存回收,优先使用ParNew+CMS(原因见后面),当用户线程内存不足时,采用备用方案Serial Old收集。

    G1收集器:在JDK1.7中正式发布,与现状的新生代、老年代概念有很大不同,目前使用较少,不做介绍。

  • 相关阅读:
    Log4net的一点改进
    SONY的几款秋季新品都还是很不错的
    在VisualStudio 工具箱中隐藏用户控件
    WPF中的DesignMode判断
    SONY的一款Win8平板
    .Net中的不可变集合(Immutable Collection)简介
    C++ 11中几个我比较喜欢的语法(三)
    很好用的谷歌字体以及Gravatar头像一键替换WordPress插件----WP Acceleration for China 插件
    关于微信获取access_token接口,返回值为-1000的问题
    主合同与补充合同的区别有哪些?
  • 原文地址:https://www.cnblogs.com/my376908915/p/6753473.html
Copyright © 2011-2022 走看看