JVM-垃圾回收(GC)

  • 为什么要了解垃圾回收?
  1. 排查内存溢出
  2. 排查内存泄漏
  3. 性能调优,排查并发瓶颈
  • 如何判断对象是否死亡

  1. 引用计数法:有地方引用它,计数器就加1;当引用失效,计数器就减1;当计数器为0时的对象可被回收;它很难解决对象之间相互循环引用的问题
  2. 可达性分析算法:通过一系列的称为 “GC Roots” 的对象作为起点,向下搜索,节点所走过的路径称为引用链,当一个对象到 GC Roots 没有任何引用链相连的话,则证明此对象是不可用的。
  3. 不可达的对象并非“非死不可”:要真正宣告一个对象死亡,至少要经历两次标记过程;可达性分析法中不可达的对象被第一次标记并且进行一次筛选,筛选的条件是此对象是否有必要执行 finalize 方法。当对象没有覆盖 finalize 方法,或 finalize 方法已经被虚拟机调用过时,虚拟机将这两种情况视为没有必要执行。被判定为需要执行的对象将会被放在一个队列中进行第二次标记,除非这个对象与引用链上的任何一个对象建立关联,否则就会被真的回收。
  • Minor GC 和 Major GC/Full GC
  1. 新生代GC(Minor GC):指发生新生代的的垃圾收集动作,Minor GC非常频繁,回收速度一般也比较快。
  2. 老年代GC(Major GC/Full GC):指发生在老年代的GC,出现了Major GC经常会伴随至少一次的Minor GC(并非绝对),Major GC的速度一般会比Minor GC的慢10倍以上。
  • JVM垃圾回收的主要区域在堆内存

 

注:在 JDK 1.8中移除整个永久代,取而代之的是一个叫元空间(Metaspace)的区域(永久代使用的是JVM的堆内存空间,而元空间使用的是物理内存,直接受到本机的物理内存限制) 

  1. Eden与S1、S2内存区域的大小比列一般为 8:1:1
  2. 新生代与老年代的大小比列一般为 1:2
  3. 永久代的垃圾回收内容主要是:废弃常量和无用的类
  4. 新产生的对象会优先存入Eden区, 如果对象过大,则大对象会直接存入Old区
  5. 当Eden区无法再放入新的对象的时候,会触发Minor GC,对整个新生代进行GC(将Eden区回收存活的对象复制到S1区,同时给存活的对象年龄标记为1,清除Eden区;下次GC时将Eden区、S1区仍然存活的对象复制到S2区同时年龄+1,然后清空Eden区、S1区,每一次GC存活对象都会在S1、S2区来回移动(目的是防止内存碎片化,保证连续的内存空间),在这期间如果有存活对象的年龄达到15(默认值)时,对象将被移到Old区
  6. 当S1区/S2区无法再存入新对象时对象会被直接存入Old区
  7. 当Old区无法再放入新的对象的时候,会触发Major GC/Full GC,对整个堆内存进行GC
  8. 当Perm区无法再放入新的对象的时候,会触发Major GC/Full GC,对整个堆内存进行GC
  • 废弃常量
  1. 没有任何对象引用的常量
  • 无用的类
  1. 该类所有的实例都已经被回收,也就是 Java 堆中不存在该类的任何实例。
  2. 加载该类的 ClassLoader 已经被回收。
  3. 该类对应的 java.lang.Class 对象没有在任何地方被引用,无法在任何地方通过反射访问该类的方法。
  • 垃圾收集算法

  1. 标记-清除算法:首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象;易产生空间碎片
  2. 复制算法:将内存分为大小相同的两块,每次使用其中的一块。当这一块的内存使用完后,就将还存活的对象复制到另一块去,然后再把使用的空间一次清理掉。这样就使每次的内存回收都是对内存区间的一半进行回收
  3. 标记-整理算法:首先标记出所有需要回收的对象,然后让所有存活的对象向一段移动,然后直接清理掉端边界以外的内存
  4. 分代收集算法:根据对象存活周期的不同将内存分为几块,根据各个年代的特点选择合适的垃圾收集算法(比如:java堆分为新生代和老年代)

 

  • 垃圾收集器
  • Serial收集器
  1. 串行收集器
  2. 新生代垃圾收集器,采用复制算法
  3. 简单而高效;单线程收集器;它在进行垃圾收集工作的时候必须暂停其他所有的工作线程( “Stop The World” ),直到它收集结束。
  • Serial Old收集器
  1. 老年代垃圾收集器,采用标记-整理算法
  • ParNew收集器
  1. 并行收集器
  2. 新生代垃圾收集器,采用复制算法
  3. Serial收集器的多线程版本,在多核CPU环境下有着比Serial更好的表现。
  • Parallel Scavenge收集器
  1. 并行收集器
  2. 新生代垃圾收集器,采用多线程和复制算法
  3. 追求高吞吐量,高效利用CPU。吞吐量一般为99%, 吞吐量= 用户线程时间/(用户线程时间+GC线程时间)
  • Parallel Old 垃圾收集器
  1. 并行收集器
  2. 老年代垃圾收集器,使用多线程和标记-整理算法。
  3. 追求高吞吐量,高效利用CPU
  • CMS(Concurrent Mark Sweep)收集器
  1. 并行收集器
  2. 老年代来及收集器,采用标记-清除算法(收集结束时会有大量空间碎片产生)
  3. 一种以获取最短回收停顿时间为目标的收集器
  4. 对CPU资源非常敏感,CPU占用比较高
  • G1(Garbage-First)收集器
  1. 并行收集器
  2. 采用标记-整理算法
  3. 以极高概率满足GC停顿时间要求的同时,还具备高吞吐量性能特征.
  4. 在G1之前的其他收集器进行收集的范围都是整个新生代或者老年代,而G1不再是这样。使用G1收集器时,Java堆的内存布局就与其他收集器有很大差别,它将整个Java堆划分为多个大小相等的独立区域(Region),虽然还保留有新生代和老年代的概念,但新生代和老年代不再是物理隔离的了,它们都是一部分Region(不需要连续)的集合。
  • 垃圾收集器使用区域

  1. 上面为新生代收集器,下面是老年代收集器
  2. 如果两个收集器之间存在连线,就说明它们可以搭配使用 
  • 垃圾回收的JVM配置

  • System.gc() 和 Runtime.gc() 
  1. System.gc();内部调用的是 Runtime.getRuntime().gc();最后调用 public native void gc();
  2. Runtime.gc();首先,没有这个调用(方法不是静态的)
  3. 提示JVM进行垃圾回收,回收方式为Full GC,但是什么时候回收由JVM决定

参考:

https://blog.csdn.net/qq_34337272/article/details/82177383

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值