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收集器.


  • 相关阅读:
    DataAnnotations
    使用BizTalk实现RosettaNet B2B So Easy
    biztalk rosettanet 自定义 pip code
    Debatching(Splitting) XML Message in Orchestration using DefaultPipeline
    Modifying namespace in XML document programmatically
    IIS各个版本中你需要知道的那些事儿
    关于IHttpModule的相关知识总结
    开发设计的一些思想总结
    《ASP.NET SignalR系列》第五课 在MVC中使用SignalR
    《ASP.NET SignalR系列》第四课 SignalR自托管(不用IIS)
  • 原文地址:https://www.cnblogs.com/snow-man/p/10552579.html
Copyright © 2011-2022 走看看