JVM GC

分代收集理论

  1. 弱分代假说:绝大多数对象都是朝生夕死
  2. 强分代假说:熬过越多次垃圾回收的对象越难以消亡
  3. 跨代引用假说:跨代引用相对于同代引用是极少数

根据1、2建立了,新生代,老年代模型,以及其适用的收集算法
根据3产生了Remember Set(卡表实现)

GC种类

Minor GC/Young GC:年轻代GC。会STW
年轻代内存分配失败时触发
Major GC/old GC:老年代GC。只有CMS有
Mixed GC:混合GC。只有G1有
Full GC:整堆回收(年轻代、老年代、方法区)

  1. 担保失败时触发
  2. 方法区满了的时候触发
  3. 老年代满了时候触发
  4. 晋升对象大于老年代剩余空间时
  5. System.gc()

垃圾回收算法

标记-清除

缺点,产生内存碎片,CMS采用此算法。
CMS提供了机制清理碎片,即每标记清除5次,进行一次标记整理

标记-整理

缺点慢

标记-复制

年轻代的SSE基于此方法,8:1:1,年轻代 : 老年代最好为1 : 2, 1 : 3.
由于8:1:1在复制的时候可能存在1的空间不足,所以引出担保机制。

  • 担保机制
    生存对象S区放不下时,放不下的部分直接进入老年代。
    担保失败:
    老年代的空间不足以放下担保进来的年轻代对象时触发。
  1. 老年代的最大可用的连续空间是否大于新生代所有对象总空间
  2. 判断是否允许担保失败(JDK 6 Update 24之前)
  3. 老年代最大连续可用空间是否大于历次晋升到老年代对象的平均大小
    2(JDK 6 Update 24之后不需要)或者3不满足的时候,进行Full GC,否则进行Minor GC。

什么样的对象直接进入老年代

  1. 大对象
  2. 15次之后
  3. 动态年龄判定(此次回收时,如果某一个年龄的对象总和大于S区的一半,则大于等于该年龄的对象直接进入老年代)
  4. 担保对象

CMS回收流程

初始标记

根结点枚举阶段
根结点枚举时候,采用 OopMap 记录,GC Root中哪些是对象(GC主要是回收对象类型)
为了更新OopMap,引出了安全点和安全区域

安全点
更新OopMap的点,也是用户线程停下来开始垃圾回收的点。
选取原则是指令复用序列之前,例如:方法调用、循环跳转、异常跳转等。

那么,下一个问题来了,线程怎么停下来。

抢占式中断
系统先中断,如果不在安全点再恢复运行
主动式中断
系统设置一个标志位,由执行线程区轮训这个标志位
现在虚拟机都采用主动式中断。
什么时候检查标志位
安全点 & 内存申请之前(因为申请内存可能会内存不足)
标志位怎么实现
内存保护陷阱的方式:
虚拟机会把一个内存设置为不可读,其他线程去读这个内存位置会出现异常,再在事先设置的异常处理器中挂起线程实现等待。


由于有些线程处于休眠状态,再次引出安全区域的概念
安全区域
安全区域是能确保在某一段代码片段中,引用关系不会发生变化的地方
线程在进入安全区域是会告诉虚拟机,虚拟机在回收垃圾时就不再关注这些线程
线程在离开安全区域时,要交验虚拟机是否完成了根结点枚举。如果没有需要一直等待。


由于跨代假说理论,所以需要Remember Set作为跨代引用的GC Root,存在年轻代,用于记录老年代对年轻代的引用,从而避免扫描整个老年代。G1里面也用来记录Region指向其他Region和其他Region指向当前Region

卡表
用于实现Remember Set,一个卡页512字节,即如果,卡表标示的起始地址为0x0000的话,rs[0]为1则0x0000~0x01FF内存中存在跨代引用
为了维护卡表引出了写屏障(区别于volatile的写屏障)类似AOP,在新建对象时会插入写后屏障保证卡表。
G1之前都是写后屏障
G1除了写后屏障维护卡表,为了实现原始快照(STAB)算法,还需使用写前屏障跟踪并发时的指针变化

卡表的伪共享问题
现在都是加载缓存行,假设缓存行64字节,由于卡表元素占用1字节,如果虚拟机同时修改764 * 512=32KB内存内的内容时,会存在伪共享问题。可以设置-XX:+UseCondCardMark来告诉虚拟机,写入之前是否查一下(如果是1就不写了)

并发标记

用户线程和垃圾回收线程共同执行。三色模型运行的第一阶段
此阶段可分为三个部分

  1. 并发标记
  2. 预清理
    重新标记并发阶段,新生代(新分配对象)和老年代变化的引用关系(采用modUnionTable记录)
  3. 可中断的预清理
    触发条件是新生代E区大于2M(默认值参数为CMSScheduleRemarkEdenSizeThreshold)
    循环处理
  4. 2中的事情
  5. 处理from和to区中的对象,标记可达的老年代对象
    退出条件是
    a. 可以设置循环次数
    b. 设置循环时间默认是5秒
    c. 上一阶段E区10%使用率,这一阶段变成了50%,上涨明显

再次标记

在并发标记阶段,由于用户线程和垃圾回收线程同时运行。引用关系会发生变化,会导致存活对象被删除的情况,所以采用此阶段进行补救。根据对象消失问题理论,只有如下两个条件都成立时才会出现对象消失问题

  1. 赋值器插入了一条或多条从黑色对象到白色对象的引用。
  2. 赋值器删除了全部从灰色对象到该白色对象的直接或间接引用。
    产生了两种再次标记算法解决如上问题:
    增量更新
    记录新的白的插入到黑的节点变化,再以这些黑色为根重新扫描(对大堆不友好,变动的黑色对象全扫一遍)
    原始快照
    记录删除了白色对象的灰色对象,再以此为根重新扫描
    G1采用此算法,实现时将删除对象作为存活对象处理

G1 SATB 致力于第二个条件的打破,利用 pre-write barrier 记录引用关系的删除,采用最保守的做法,把变更前的引用对象记录下来,当作是存活对象,让其活过这一周期;另外之前也提及了,SATB 在初始标记的时候打了快照,NextTAMS 指针之后的的对象也在这一个周期里隐式存活,因此 G1 的 SATB 会产生更多的浮动垃圾。但是换来的好处就是,不需要像 CMS 那样 remark,再走一遍 root trace 这种相当耗时的流程

并发清除

并发清除

经典垃圾收集器

Serial(New Old)

单线程,桌面版采用。
新生代:标记复制
老年代:标记整理

ParNew(New)

就是Serial的并行版本,只有他可以和CMS配合
并发:用户线程和垃圾回收线程
并行:垃圾回收线程之间

Parallel Scavenge(New)Parallel Old(是Parallel Scavenge的老年代收集器)

关注吞吐量

CMS

默认线程数是(处理器核心数+3)/4
Concurrent Mode failure会冻结用户线程采用Serial Old来兜底

G1

多个Region(S,E,O,Humongous)取值为1-32MB
维护双向卡表
TAMS,用户回收时分配对象,保证TAMS指针之间的内容不会被回收

G1 vs CMS

G1
可以指定最大停顿时间
不会产生内存碎片
原始快照消耗小,最终标记时停顿短
CMS
内存占用小(G1有双向卡表,且每个Region都有维护,可能占堆的20%)
内存屏障消耗小

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,366评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,521评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,689评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,925评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,942评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,727评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,447评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,349评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,820评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,990评论 3 337
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,127评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,812评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,471评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,017评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,142评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,388评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,066评论 2 355