JVM--垃圾回收机制

1.JVM堆的基本结构

在这里插入图片描述

1. JVM堆空间分为:Java堆和方法区(元空间/永久代)
2. Java堆从GC的角度可以细分为:新生代和老年代

(因此JVM堆可以分为三大区:新生代、老年代、永久代)

3. 新生代又可以细分为:Eden区、两个幸存区(Survivor-From区、Survivor-To区)
	* Eden区:new出来的对象都会存储到Eden区(较大对象会直接存储到老年区)
	* Survivor-From区:上一次GC的幸存者,第一次出现对象是从Eden区分配过来的
	* Survivor-To区:将GC的幸存者复制到该区后,该区将会变为下一次GC的FROM区,原来的From区将会变成To区。to区和from区总是相互复制、相互转换的
  • 堆内存大小占比:Eden区:Survivor-FROM区:Survivor-To区<=>8:1:1(可以通过-XX:SurvivorRatio修改Eden区内存占比,默认值是8)
  • 新生代占Java堆内存的1/3(可以通过参数-XX:NewRatio修改,默认值是2,如果-XX:NewRatio=3,则新生代和老年代的占比为1:3)
4. 老年代
	* 当新生代每进行一次GC,年龄就会+1,直到年龄>=15就会被分配到老年代(-XX:MaxTenuringThreshold)默认值=15
	* 老年代占Java堆内存的2/3
	* 较大对象会直接存储到老年区
	* 存活的对象太多,无法保存在Survivor时会直接进入老年区

注意:new的对象字节大小超过-XX:PretenureSizeThreshold设置的值,则会直接进入老年区

5. 永久代
	* 永久代为`JDK1.8`以前的说法,之后称为`元空间`
	* 元空间是方法区(永久代/元空间))的具体实现
	* 永久代内存不足会触发虚拟机的full GC,而元空间是采用本地内存进行存储,因此不会触发虚拟机的Full GC

2.GC垃圾回收机制

什么是GC?
	GC是垃圾收集的意思,如果不进行垃圾回收,容易造成OOM
可以手动进行垃圾回收吗?
	不可以!但是可以通过System.gc()通知GC进行垃圾回收(GC不一定执行)
GC是如何判断对象是否是垃圾的?
	两种方式:
		可达性分析算法:采用有向图的方式记录和管理堆中的所有对象,从有向图的根节点(GC Root)开始搜索,当有向图的路径(引用链)为不可达,则GC会标记该对象为不可达对象,并在第二次标记时,如果引用链还未关联,则视为可回收对象,并进行回收
		引用计数器算法:为每个对象创建一个引用计数,有对象引用时计数器+1,引用被释放时计数-1,当计数器的值为0时GC就会将该对象进行回收(缺点:不能解决循环引用的问题 被主流JVM抛弃)
2.1GC回收器分类
  • 新生代收集器(复制算法)
    • 常用的收集器:Serial、PraNew、Parallel Scavenge
      • Serial收集器(单线程收集器):标记和清理都是单线程,优点是简单高效
      • PraNew收集器(并行收集器):Serial的多线程版本,在多核CPU环境下比Serial更高效
      • Parallel Scavenge收集器(并行收集器):追求高吞吐量,高效利用CPU。吞吐量=用户线程时间/(用户线程时间+GC线程时间),可尽快完成程序的运算任务,适合后台应用等,对交互响应要求不高的场景。
  • 老年代收集器
    • 常用的收集器:Serial Old、CMS、Parallel Old
      • Serial Old收集器(标记-整理算法):老年代单线程收集器
      • CMS(标记-清除算法):老年代并行收集器,以获取最短回收停顿时间为目标的收集器,具有高并发、低停顿的特点,追求最短GC回收停顿时间。
      • Parallel Old(标记-整理算法):老年代并行收集器,吞吐量优先
  • G1收集器(标记-整理算法)
    • Java堆并行收集器,G1收集器是JDK1.7提供的一个新的收集器,G1收集器基于"标记-整理"算法实现,也就是说解决了内存碎片的产生问题,且G1的回收范围是整个Java堆(包括新生代、老年代)
2.2GC收集器使用的过程
  • 新生代收集器称为:MinorGC

    • 当Eden区满了以后,此时会采用可达性分析算法对Eden区的数据进行标记清除,剩余存活对象将被复制到幸存区(Survivor-From),清空Eden区域对象,如图所示:
      在这里插入图片描述
    • 当Form幸存区满了以后触发第二次MinorGC,此时将会利用可达性分析算法判断Eden区和Form区标记的可回收对象并清理,利用复制算法将Eden区和Form区存活的对象复制到To区,并清空Eden区和Form区的对象
      在这里插入图片描述
    • Survivor-From区更名为Survivor-To区,而原Survivor-To区替换为Survivor-From区
    • 下一次GC同样会把Eden区和现在的Form区存活对象复制到To区,如此往复,直到对象年龄>=15则会被分配到老年区
  • 老年代收集器称为:MajorGC

    • 当新生代对象分配到老年代,导致内存空间不足,触发MajorGC;或new的对象过大,直接分配到老年代时无法找到连续内存空间分配给该对象时,也会提前触发MajorGC
首先会扫描一次所有的老年代对象,标记存活对象,该过程称为标记阶段

在这里插入图片描述

标记后会将可回收对象清理,该过程称为清理阶段

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值