JVM之GC详解

垃圾收集(Garbage Collection,GC),Java进程在启动后,会创建垃圾回收线程,对内存中无用的对象进行回收

垃圾回收策略

垃圾回收某个对象时,首先要判断这个对象是否可回收,有两种算法:
1、引用计数算法
原理:给对象添加引用计数器,有地方引用,计数器加1;引用失效,计数器减1;计数器为0时可回收。
缺陷:很难解决对象之间相互循环引用的问题
2、可达性分析算法
原理:通过一系列的称为“GC Roots”的对象作为起始点, 从这些节点开始向下搜索, 搜索所走过的路径称为引用链,当一个对象到GC Roots没有任何引用链相连,证明此对象不可用。Java语言使用可达性算法进行垃圾回收

需要垃圾回收的内存

需要垃圾回收的区域:方法区(jdk1.7)/元空间(jdk1.8),堆
jdk1.7的方法区在GC中一般叫做永久代

Java堆是垃圾收集器管理的主要区域,从内存回收角度看,收集器采用分带收集算法,所以堆可以细分:
1、新生代:又分为Eden区和S区
新生代垃圾回收又称为Young GC (YGC)、Minor GC
Minor GC非常频繁,一般回收速度比较快

2、老年代
老年代垃圾回收又称为Major GC
Major GC的速度比Minor GC慢10倍以上

3、Full GC
不同语义下,对Full GC的定义不同,有时候指的是老年代的垃圾回收,有时候指的是全堆(新生代+老年代)的垃圾回收
在这里插入图片描述

堆的GC

1、新生代GC:——Eden区和使用的S区,存活对象,复制到留空的S区。GC前后,两块S区的角色发生转变
Eden:
      进入对象的条件: 创建对象时,优先分配的区域——空间不足,触发Minor GC(新生代GC)
Survivor:一块保存对象,一块留空
      进入对象的条件:触发Minor GC时,留空的S区,会进入GC后存活的对象——空间不足,进入老年代
2、老年代GC:——空间不足触发Major GC(老年代GC)
进入对象的条件:
(1)大对象直接进入——空间不足,触发Major GC(老年代GC)
(2)长期存活的对象进入老年代——对象年龄>阈值(默认是15)
(3)Minor GC时,留空S区空间不足存放GC后的存活对象,所有存活对象,进入老年代

Minor GC步骤:
(1)复制存活对象到Survivor区另一块——存活对象年龄+1
(2)清空Eden区和前一块Survivor区
(3)给需要创建的对象分配内存
异常情况:如果留空的S区空间不足存放GC后的存活对象时,所有存活对象,通过分配担保机制,进入老年代

垃圾回收算法

1、标记-清除(Mark-Sweep)
(1)分为两个阶段:标记、清除
(2)老年代的回收算法
(3)不足:
            效率不高
            产生大量不完整的内存碎片——导致:再进入大对象,如果没有连续空间存放,触发Major GC

2、复制算法(Copying)
(1)新生代回收算法
(2)内存使用率不高——50%
(3)优点:实现简单、运行高效、不存在内存碎片问题

3、标记-整理算法
(1)老年代回收算法
(2)两个阶段:标记、整理(移动存活对象到一端内存,清理另一端内存)

垃圾收集的影响

STW

STW(Stop The World):GC导致的暂停用户线程
(1)原因:用户线程和GC线程并发、并行的执行,标记可回收的对象,在用户线程并发执行时,可能重新有引用 指向该对象
(2)GC时:什么情况会STW?
          新生代GC:都会STW——影响:因为Minor GC时间非常快,几乎忽略不计,影响很小
          老年代GC:根据阶段来看是否会STW——影响:非常大(老年代空间大,需要回收的对象多,耗时也多)
Full GC一般是指影响很大(STW),所以一般都包含Major GC

吞吐量和用户体验

吞吐量:总的停顿时间越短,吞吐量越好
用户体验(停顿时间):单次停顿时间越短,用户体验越好

统计结果表示:
(1)在固定时间内来计算,单次STW时间越长,STW总时间越短。反比关系。
(2)用户体验和吞吐量就对应的表现出反比关系。

垃圾收集器

新生代收集器

1、Serial:单线程、STW、复制算法

2、ParNew:多线程、STW、复制算法——和CMS搭配使用,在用户体验优先的程序中使用

3、Parallel Scanvenge
     (1)多线程、STW、复制算法
     (2)吞吐量优先 主要是后台任务型程序(比如定时任务,不涉及用户使用的程序)
     (3)自适应的调节策略:JVM设置这个参数=true后,JVM可以监控性能,并动态的设置内存相关参数(如年龄阈值,新生代大小,Eden和S区比例)

老年代收集器

1、Serial Old:单线程、标记整理算法——CMS在发生并发失败(Concurrent Mode Failure)时作为备用垃圾回收方案

2、Parallel Old
     (1)多线程、标记整理算法、STW
     (2)吞吐量优先——搭配Parallel Scanvenge一起使用

3、CMS(Concurrent Mark Sweep):
(1)标记清除算法
(2)用户体验优先
(3)分为四个阶段
          初始阶段:标记GC Roots能直接关联的对象,速度很快,STW
          并发标记:GC Roots Tracing
          重新标记:STW,解决第二个阶段,用户线程并发执行,导致已经标记的对象(可回收)被重新引用(有GC Roots变量指向该对象)
          并发清除:并发清除对象
(4)缺陷
CMS垃圾回收线程会抢占CPU资源,导致用户线程总的执行时间更少

浮动垃圾问题
      1)产生原因:CMS第四个阶段,用户线程并发执行又可能导致有对象进入老年代,而老年代也可能空间不足,触发Major GC——Concurrent Mode Failure
      2)解决方案:使用Serial Old进行垃圾回收
      3)标记清除算法会导致老年代空间碎片,如果进入的对象没有连续的可用空间,触发Full GC

四个阶段中
      1)1和3执行速度快,消耗时间少——暂停用户线程时间少
      2)2和4,执行时间相对较慢,但是可以和用户线程并发执行
总体来看,CMS垃圾回收的工作是和用户线程同时执行——CMS名称的由来

java引用类型

强引用:代码中普遍存在的,类似“Object obj=new Object()”这类的引用,只要强引用存在,垃圾收集器就永远不会回收掉被引用的对象。

软引用:在系统将要发生内存溢出之前,会把软引用关联的对象回收,如果这次回收后还没有足够的内存,才会抛出内存溢出

弱引用:强度比软引用更弱,被软引用关联的对象只能生存到下一次垃圾收集发生之前。垃圾收集器工作时,无论内存是否足够,都会回收被弱引用关联的对象

虚引用:最弱的引用关系。一个对象是否有虚引用的存在,完全不会对其生存时间构成影响,也无法通过虚引用来取得一个对象实例。设置虚引用的目的是能在对像被收集器回收时收到一个系统通知

在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值