JVM系列(三)

JVM内存模型

对于JVM来说,在哪个区就采取相应的垃圾回收机制

对于s0和s1,在同一个时间点,只有一个是启动的,另外一个是空的

Student stu = new Student();

对于上面代码,new出来的对象stu,首先会分配在eden区,如果eden区满了就会触发第一次GC,这次GC会把活的对象拷贝到s0

如果eden区第二次满了,那么会再次触发GC,此时,eden和from区会再次被扫描,对这两个去进行垃圾回收,如果还有存活的,就把它们全都放在s1区

每扫一次,对象年龄会+1,JDK8,默认是15次,也就是说,s0和s1进行互换的时候,原来的s0经过GC就会变成s1,这样对象就会复制过来,复制过去。当你的年龄到了15,就会把它干到老年代。也有可能你的对象一进来就比较大,也有可能会把它直接干到老年代。

三个需要注意的参数

  • -XX:SurvivorRatio=8    eden:s0:s1 = 8
  • -XX:NewRatio=2          新生代和老年代在堆中的内存占比
  • -XX:MaxTenuringThreshold=15    如果MaxTenuringThreshold=0,就是年轻代的对象不经过survivor,直接进入老年代

真正要做GC的是在堆区

非堆区是独立于堆之外的,是不受JVM的管控

Metaspace存放Class Package Method Field 字节码 常量池等等

 

JMM Java内存模型

 

先要明确哪些对象需要回收

  1. 引用计数 
    父类引用指向子类对象,体现了Java的多态
    如果B里有A,A里有B就相当于死锁了,循环引用,就不能标记为垃圾
  2. 枚举根节点可达性分析,从根节点开始的可达性分析

根节点有很多类型的

CG算法

  1. 标记-清除 Mark-Sweep
  2. 复制 Copy
  3. 标记-整理 Mark-Compact,基于标记-清除做的优化
  4. 分带 是前面三个的整合

下面分别说说这四种垃圾回收机制

标记-清除 Mark-Sweep

  • 标记:从GC Roots开始找,找到所有存活的对象并标记
  • 清除:将没有标记的对象干掉

性能比较高

存在的问题:所有的内存都是碎的,内存碎片

 

复制 Copy

复制会把内存划分为两个区域,统一时间点,只有一个是活动的,当我们的内存不够的时候,JVM会停止我们的应用程序,然后启用复制算法

GC线程会将活动区域的存活对象全部复制到空闲区域,内存地址是排序的

这样布局就没那么混乱

缺点:真正能用的内存只有一半

对于90%的对象,自创建开始没一会就会被销毁的

适用于新生代GC

标记-整理 Mark-Compact

  • 标记
  • 整理 会对内存的地址做一次排序

弥补了标记-清除内存区比较分散的缺点

跟Copy相比,Copy的性能会更好一些

分代

前面三者的综合使用,比如说新生代采取什么算法,老年代又是采取什么算法

新生代使用复制

老年代使用标记-清除或者标记-整理

 

结合Spark来说说线上遇到的OOM异常以及解决方案

  • Spark内存模型
  • Spark架构
  • JVM OOM

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值