• Java垃圾回收


    1、 Java GC堆内存分配。

    2、晋升年龄(默认是15岁,Hotspot是动态年龄判定,遍历所有对象,按照年龄从小到大对其占用的大小进行累积,当累积到某个年龄超过了survivor的50%取这个年龄为晋升阈值。)

    GCRoot对象

    1、虚拟机方法栈(栈帧中的本地变量表)中的引用变量。

    2、本地方法栈中的引用变量。

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

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

    5、所有被同步锁持有的对象。

     方法区中存储了:1、类信息(包括了JVM加载类型:类class、接口interface、枚举enum)、直接父类的完整有效名称、类型修饰符2、成员变量信息3、静态变量4、运行时常量池:各种字面量和类型等引用。

     加入eden和from都有对象,那么将这两个地方的对象都复制到to区,然后交换from和to。

    GC规模

    1、MinorGC发生在新生代的垃圾回收,暂停时间短

    2、MixedGC新生代+老年代部分区域的垃圾回收,G1收集器特有

    3、FullGC新生代+老年代 完整垃圾回收,暂停时间长,尽力避免

    1.1对象优先在eden区分配

    大多数情况下,对象在新生代中eden区分配,当eden没有足够多空间分配的时候,虚拟机将发起一次MinorGC

    针对HotSpotVM的实现,里面的GC主要分为两大种:

    部分收集(PartialGC)

      1、新生代收集(MinorGC/Younggc):只对新生代进行垃圾收集 

      2、老年代收集(MajorGC/OldGC):只对老年代进行垃圾回收,需要注意的是MajorGC在有语境中也用于指代整堆收集

      3、混合收集(MixedGC):对整个新生代和部分老年代进行垃圾收集

    整堆收集(Full GC):对整个JAVA堆和方法区收集。

     ConcurrentMarkSweepGC(CMS)

    1、old并发标记,重新标记时需要STW,并发清楚

    2、failback full gc 

    3、缺点会有内存碎片

    4、注重响应时间

    二、垃圾回收器

    7种垃圾收集器与垃圾分代之间的关系

    Parallel GC(吞吐量优先 )

    1、eden内存不足发生MinorGC,标记复制STW不会有碎片

    2、old内存不足发生FullGC,标记整理STW不会有碎片),暂停时间更长,因为要完整的回收。  

    3、注重吞吐量。(比如消息队列的消息传过来后涉及大量的计算,而不是立即与用户做交互,工资支付,科学计算等)

    在吞吐量优先的场景,paralle收集器与parallelold收集器的组合,在server模式下内存回收性能不错。二者是相互激活的  

    可以设置的参数

    最大停止时间、使用自适应调优策略。

     互联网请求尽量不要暂停。

    大量计算响应时间,响应时间久一点,但是整体上时间短就行。

     

     JDK8 默认使用的是Parallel Scavenge

    垃圾回收器:

    ConcurrentMarkSweep GC (CMS)(用的三色标记算法 黑灰白,标记两次,因为在第一次标记的完后,用户线程可能更改引用,然后进行第二次标记,第二次标记不会被清理,只有第二次cms才会清理)

    1、old并发标记,重新标记时需要STW,并发清除 (会存在内存碎片)

    2、Failback full gc

    3、注重响应时间。 并发导致线程去做垃圾对象标记,所以吞吐量会变低。 

    弊端:

    参数使用  手动指定cms收集器,  -XX:+useConcMarkSweepGC、设置CMS线程数。

    jdk9以后  G1GC(以后默认的垃圾回收器,在保证吞吐量优先的情况下,降低停顿时间)

     1、并发与并行:在多核环境下能够使用多个CPU来缩短STW的停顿时间。部分其他收集器原本需要停顿java线程,执行GC动作,G1收集器仍然可以通过并发方式让java继续执行。

     2、分代收集:虽然G1可以不需要其他收集器就能独立管理整个GC堆,但是还是保留了分代回收

     3、空间整合:与CMS的“标记-清理”算法不同,G1从整体来看是基于“标记-整理”算法实现的收集器。从局部看是标记复制

     4、可预测的停顿:G1的优势,降低停顿时间是CMS和G1共同关注的,但G1追求停顿的外,还可以建立可预测的时间模型,使使用者明确指定长度M毫秒时间内。

    垃圾回收步骤:

      1、初始标记

      2、并发回收

      3、最终标记

      4、筛选回收

      G1收集器在后台维护了一个优先列表,每次根据允许的收集时间,优选选择回收价值最大的Region。这种Region划分内存空间以及有优先级的区域回收方式,保证了G1收集器在有限时间内尽可能收集更多内存。

     优势:

      

     eden区回收复制到Survivor区 

     从经验来说,小内存应用上CMS的表现大概率会高于G1,G1在大内存应用上发挥起优势。 

    CMS需要额外的空间,额外负载,rset来记忆,避免全局扫描。

    G1回收期场景操作步骤
    1、开启G1垃圾收集器

    2、设置堆的最大内存

    3、设置最大的停顿时间

    回收过程:

    1、年轻代GC minor gc

    2、老年代并发标记 

    3、混合回收mixed gc(全部新生代和部分老年代,部分老年代根据回收价值绝对那个先回收)

    如果需要针对GC评估失败,提供一种失败保护机制,即强力回收。

    G1垃圾回收期具体过程:

    1、

    2、

    1、响应时间与吞吐量兼顾

    2、划分多个区域每个区域可以充当eden survivor humongous

    3、新生代回收:eden内存不足,标记复制 stw

    4、并发标记:old并发标记,重新标记需要stw

    5、混合收集:并发标记完成,开始混合收集,参与复制的eden、survivor、old,其中old会根据暂停时间目标,选择回收价值高的区域,复制时STW

    6、failback full gc

    Serial回收器:串行回收

    最基本最老的收集器。采用的复制算法、串行回收和stw机制进行内存回收。

     总结:

    这种垃圾收集器,现在不用串行的了,而且在限定单核cpu才可以用,对于交互性强的应用而言,这种垃圾收集器是不能接收的。一般在javaweb应用程序中是不会采用串行垃圾收集器的。

    ParNew回收期

    除了收集器采用的是并行回收的方式以外,两款垃圾收集器几乎没有任何区别。parnew同样也是采用复制算法,“stop the world”机制

    parnew 是很多jvm运行在server模式下新生代的默认垃圾收集器。

    小结:

    如果想要最小化地使用内存和并行开销,选Serial GC;

    如果想要最大化地应用程序,选Parallel GC

    如果想要最小化GC中断或者停顿时间,选CMS GC

    判断对象死亡:

    1.1引用计数法:(目前基本不用了)

    如果对象有引用就不是死亡,但是会出现循环引用的现象。回收不了

    1.2可达性分析算法

    基本思想:通过一系列的GCRoots的对象作为起点,从这些节点开始向下搜索,节点所走过的路径称为引用链,当一个对象到GC Roots每页任何引用链引用的话,则需要回收

    那些对象可以作为GC Roots呢?

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

    2、本地方法栈(Native 方法)中引用的对象

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

    4、方法区中常量引用的对象

    5、所有被同步锁持有的对象

    三、对象可以被回收,就一定可以被回收吗?

    即使在可达性分析法中不可达的对象,也并非是非死不可的,因为可能处于缓刑状态,真正宣告一个对象死亡,

    至少要经历两次标记过程;可达性分析法中不可达的对象被第一次标记并且进行筛选,筛选的条件是次对象是是否有必要

    执行finalize的方法。当对象没有覆盖finalize方法,或者finalize方法已经被虚拟机调用过的时候,虚拟机将这两种情况视为没有必要执行。

    被判定为需要执行的对象将会被放在一个队列中进行第二次标记,除非这个对象与引用链上的任何一个对象建立了联系,否则就会真的被回收。

    finalize方法弊端(每个类都有finalizer,它不能被直接调用,而被jvm在适当的时候调用,作为一种收尾机制):

    1、行为不稳定

    2、降低性能

    3、可移植性低

    (使用finalizer最严重的缺点是不能保证被执行,一个对象变得不可达开始,一直到该对象被jvm终结,过程中时间是未知的。当一个类提供了finalizer,会查看finalizer队列是否很多实例等待被终结。

         

    面试题:说说GC和分代回收算法

    GC目的在与实现无用对象内存自动释放,减少内存碎片、加快分配速度。

    GC要点:

    1、回收区域是堆内存,不包括虚拟机栈,在方法调用结束会自动释放方法占用的内存

    2、判断无用对象,使用可达性分析算法三色标记法标记存活对象,回收未标记的对象

    3、GC具体的实现称为垃圾回收器(G1,CMS,PC)

    4、GC大都采用分代回收思想,理论依据大部分朝生夕灭,用完立刻就会回收,另有少部分对象会长时间存活,

    每次很难回收,根据这类对象特性分为新生代老年代,不同区域回收策略不同。

    5、根据GC规模可以分为MinorGC,MixedGC,Full GC(老年代不足)

    三色标记与并发漏标问题

    1、用三种颜色记录对象的标记状态

    1.1 黑色-已标记(沿着根对象的引用链找到了这个对象,并且这个对象内部其他引用都处理完了)

    1.2 灰色-标记中(沿着根对象的引用链找到了这个对象,但是这个对象内部其他引用未被处理)

    1.3 白色-未被标记(未被处理)

     三色标记与并发漏标问题

    产生漏标问题-记录标记过程中的变化

     解决方案:

    1、increment update

      1.1只要发生了赋值,被赋值的对象就 会被记录(变为灰色)

    2、Snapshot at the beginning satb

      2.1新对象会被记录

      2.2被删除引用关系的对象也会被记录

    评估GC的性能指标

    1、吞吐量 a/(a+b)

    2、垃圾手机开销:b/(a+b)

    3、暂停时间:执行垃圾收集时,程序工作被暂停的时间。

    4、收集频率:相对于应用程序执行,收集操作发生的频率。 (频率低可能会造成暂停时间长,频率高,暂停时间短)

    5、内存占用:Java堆区所占的内存大小

    6、快速:一个对象从诞生到回收经历的时间。

    标记的这个三个构成了“不可能三角”。

    主要关注(吞吐量、暂停时间)

    高吞吐量的应用程序有更长的时间基准,快速响应是不必考虑的。

    垃圾回收器总结:

     Serial=>parallel并行=>cms(并发)=>G1=>ZGC

      

  • 相关阅读:
    weiPHP微信开发框架
    win7系统
    csdn博客频道
    一步一步安装Git控件版本工具
    php源码,php网站源码,php源码下载
    czz数据专家
    禁用了传说中的PHP危险函数之后,Laravel的定时任务不能执行了?
    php禁用函数设置及查看方法详解
    laravel项目thinksns-plus安装出现RuntimeException Symlink from * to * failed错误
    laravel框架使用中错误及解决办法总结
  • 原文地址:https://www.cnblogs.com/Alei777/p/16228274.html
Copyright © 2020-2023  润新知