阿里面试P8 2020 JVM 垃圾回收算之 CMS会出现的问题(三面问题)

在说明CMS 会出现问题的同时我们先了解一线CMS的垃圾回收的算法,CMS 是采用的是mark-sweep 算法(标记清除算法)。

 mark-sweep 的算法如下图所示:

1.可以看出这个算法出现的问题之一,”内存会有碎片化的问题“,一般分配创建对象分配内存有两种方式,第一种是通过获取连续的存储空间(Cms 是这种 都是内存连续的分大块的),如果没有连续的存储空间,第二种通过复杂的内存管理器来实现,这里有点像你去网吧上网,你需要问前台小姐姐那台电脑是空的,你和你的朋友去坐,很有可能是分开做的,这种方式增加了对于可用内存未使用内存的管理(这里要说这种方式目前G1 是有这样的内存管理机制,还有注意的点就是G1 内存管理的Region,G1不会出现内存碎片化问题,因为它回收的单位是Region)

2. 宁外还有一个问题就是”浮动垃圾“(浮动垃圾是指在垃圾回收的时候新增的垃圾)的问题,首先我们在日志中可以看到两个信息。

    2.1  Concurrent Mode Failure 

    2.2  PromotionFaild

 出现这两个信息的原因是old 区占满了但是从young区过来的对象过来不了,就会报这个错,解决方案是:

1、cms 进行回收的时候,会产生一部分浮动垃圾,这些垃圾会放到一个队列中,等待下一次的回收来进行回收,这种情况就会让old区没有更多的内存空间,于是降低设置CMS的阈值是我们解决这个问题的一个方法,目的是预先腾出空间让young区过来的对象在old 区有一个家(针对与jdk1.8 这个阈值默认是92% jdk 1.7 是68%,这里最好是设置80% ,因为阀值设置的越高,内存的利用率确实高了,但是在浮动垃圾比较多的情况下这里从young 过来一些大对象,他会放不下,经过测试出来的结果分析了一下,80%比较合理 可以通过 -XX:CMSIntitaingOccupanyFraction 80% 来进行设置)这个阀值是GC 执行FULL GC  的一个因素。

2、解决方案是保持老年代足够的内存空间,但是这里要注意两件事情,内存不是设置越多越好,而是需要设置合适的比较好,因为cms 本身就不是为大内存,内存越大,如果出现了碎片化无法获取到新的内存时,cms 会启动 searial-old (串行化进行mark-conpact 标记整理),这样STW 时间就比较长了(searial-old 会出现很长的STW 因为是单线程清理,并且停掉所有的用户线程,这样可想而知性能慢,STW会时间比较长,这里为啥不知道为什么不用 Parall old,这里无从得知至少你用个多线程并发呀),这里参考的是阿里的哥们所说的2012年,有时候会出现20多分钟的停顿的情况。(这里还需要注意一个点就是 -XX:CMSFULLGCsBeforeCompaction  这个参数的默认值是0 指的是经历过多少次的FGC 数量才进行数据压缩整理)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值