zoukankan      html  css  js  c++  java
  • JVM 垃圾回收算法

    在JAVA语言中可以作为GC Root的对象包括下面几种:

      局部变量表中引用对象

      静态属性引用的对象

      方法区常量 引用的对象

      本地方法栈中(JNI)引用的对象.

    永生代中垃圾收集主要回收两部分内容:废弃常量和无用的类. 

    在大量使用反射、动态代理、CGLib等ByteCode框架、动态生成JSP以及OSGi这类频繁自定义ClassLoader的场景都需要虚拟机具备类卸载的功能,以保证永久代不会溢出。

    垃圾回收算法:

    1. 标记情书算法(Mark-Sweep): 最基础的收集算法, 会有两个问题: 标记和清除两个过程的效率都不高;另一个是空间问题,标记清除之后会产生大量不连续的内存碎片
    2.  复制算法; 特点:实现简答高效, 但会浪费一部分内存, HotSpot虚拟机默认Eden,Survivor的大小比例是8:1,这样只有10%的空间被"浪费"
    3. 标记整理算法: 针对老年代对象存货效率较高, 又不想浪费空间设计了本算法:  与标记清除算法相似, 但后续步骤不是直接对可回收对象进行清理,而是让所有存活的对象都向一端移动,然后直接清理掉端边界以外的内存..
    4. 分代收集算法: 根据对象存活周期将内存划分为几块: 一般是分为新生代和老年代. 新生代每次都有大量对象死去,所以使用复制算法, 老年代对象存活率高, 使用标记整理算法.

    如果说收集算法是内存回收的方法论,那么垃圾收集器就是内存回收的具体实现.

    Serial收集器:

    是虚拟机运行在Client模式下的默认新生代收集器, 

    特点: 单线程收集器, 它工作时会暂停所有其他线程, 真正实现"Stop the world",

    优点: 简单高效,尤其是放在client端.

    ParNew收集器

    ParNew收集器除了多线程收集之外,其他与Serial收集器相比并没有太多创新之处,但它却是许多运行在Server模式下的虚拟机中首选的新生代收集器,其中有一个与性能无关但很重要的原因是,除了Serial收集器外,目前只有它能与CMS收集器配合工作,

    ParNew收集器在单CPU的环境中绝对不会有比Serial收集器更好的效果,甚至由于存在线程交互的开销,该收集器在通过超线程技术实现的两个CPU的环境中都不能百分之百地保证可以超越Serial收集器。当然,随着可以使用的CPU的数量的增加,它对于GC时系统资源的有效利用还是很有好处的。它默认开启的收集线程数与CPU的数量相同,在CPU非常多(譬如32个,现在CPU动辄就4核加超线程,服务器超过32个逻辑CPU的情况越来越多了)的环境下,可以使用-XX:ParallelGCThreads参数来限制垃圾收集的线程数。

     

    Parallel Scavenge收集器

    Parallel Scavenge收集器是一个新生代收集器,它也是使用复制算法的收集器,又是并行的多线程收集器, 是吞吐量优先的收集器.

    吞吐量=运行用户代码时间/(运行用户代码时间+垃圾收集时间)

    Serial Old收集器

    Serial Old是Serial收集器的老年代版本,它同样是一个单线程收集器,使用“标记-整理”算法

    这个收集器的主要意义也是在于给Client模式下的虚拟机使用。如果在Server模式下,那么它主要还有两大用途:一种用途是在JDK 1.5以及之前的版本中与Parallel Scavenge收集器搭配使用[1],另一种用途就是作为CMS收集器的后备预案.

    Parallel Old收集器

    Parallel Old是Parallel Scavenge收集器的老年代版本,使用多线程和“标记-整理”算法。这个收集器是在JDK 1.6中才开始提供的,

     

    CMS(Concurrent Mark Sweep)收集器

    是一种以获取最短回收停顿时间为目标的收集器。目前很大一部分的Java应用集中在互联网站或者B/S系统的服务端上.CMS收集器是基于“标记—清除”算法实现的,它的运作过程相对于前面几种收集器来说更复杂一些,

    整个过程分为4个步骤,包括:

    1. 初始标记(CMS initial mark) :  会stop the world, 只从GCRoot标记第一层
    2. 并发标记(CMS concurrent mark)
    3. 重新标记(CMS remark):会stop the world, 主要是为了修正并发标记时,用户对象位置的修改.
    4. 并发清除(CMS concurrent sweep)

     不足:

    1. 对CPU资源敏感, 占用一部分资源.;
    2. 无法处理浮动垃圾. 
    3. 因为是标记清理算法,所以会产生碎片.

     

     G1 收集器:

    它将整个Java堆划分为多个大小相等的独立区域(Region),虽然还保留有新生代和老年代的概念,但新生代和老年代不再是物理隔离的了,它们都是一部分Region(不需要连续)的集合。

     

    如果不计算维护Remembered Set的操作,G1收集器的运作大致可划分为以下几个步骤:

    1. 初始标记(Initial Marking)
    2. 并发标记(Concurrent Marking)
    3. 最终标记(Final Marking)
    4. 筛选回收(Live Data Counting and Evacuation)

     

    ZGC收集器: 

    JAVA 11 新GC收集器.


  • 相关阅读:
    C#与数据库访问技术总结(十四)之DataAdapter对象
    《运维三十六计》:运维生存宝典
    企业运维几百个重点面试题汇总(老男孩)
    5、KVM虚拟化典型案例:生产环境问题案例与分析
    Linux运维必会的实战编程笔试题(19题)
    面试中常见的 MySQL 考察难点和热点
    Linux系统运维常见面试简答题(36题)
    一键备份脚本 backup.sh
    Linux常用的200个命令总结分类
    2、KVM虚拟化CPU、内存、网络、磁盘技术及性能调优方法
  • 原文地址:https://www.cnblogs.com/snow-man/p/10552579.html
Copyright © 2011-2022 走看看