当代主流虚拟机(Hotspot VM)的垃圾回收都采用“分代回收”的算法。“分代回收”是基于这样一个事实:对象的生命周期不同,所以针对不同生命周期的对象可以采取不同的回收方式,以便提高回收效率。
- 新生代:分三个区:一个Eden区,两个Survivor区,默认内存占比8:1:1。大部分对象在Eden区中生成。当Eden区满时,还存活的对象将被复制到两个Survivor区(中的一个)。当这个Survivor区满时,此区的存活且不满足“晋升”条件的对象将被复制到另外一个Survivor区。对象每经历一次Minor GC,年龄加1,达到“晋升年龄阈值”后,被放到老年代。
- 老年代:在新生代中经历了N次垃圾回收后仍然存活的对象,就会被放到年老代。
- java8已经没有持久代了,改为元数据区,主要存放元数据,例如Class、Method的元信息。
对象分配过程
- 对象比较大的时候,超过-XX:PretenureSizeThreshold设置值时,直接分配到老年代;
- 向eden申请空间创建新对象,eden没有合适的空间,因此触发minor gc
- minor gc将eden区及from survivor区域的存活对象进行处理:
- 如果这些对象年龄达到阈值(MaxTenuringThreshold),则直接晋升到年老代
- 若要拷贝的对象太大,那么不会拷贝到to survivor,而是直接进入年老代
- 若to survivor区域空间不够/或者复制过程中出现不够,则发生survivor溢出,直接进入年老代
- 其他的,若to survivor区域空间够,则存活对象拷贝到to survivor区域
- 此时eden区及from survivor区域的剩余对象为垃圾对象,直接抹掉回收,释放的空间成为新的可分配的空间
- minor gc之后,若eden空间足够,则新对象在eden分配空间;若eden空间仍然不够,则新对象直接在年老代分配空间
垃圾回收器
- 新生代收集器有:Serial(单线程),ParNew(多线程),Paraller Scavenge(侧重于吞吐量控制)
- 老年代收集器有:CMS(获取最短回收停顿时间为目标的回收器,该回收器是基于“标记-清除”算法实现的), Serial old,Parallel Old
- G1收集器可作用与新生代和老年代(JDK9默认垃圾收集器)
ParNew+CMS工作机制
-XX:+UseConcMarkSweepGC
-XX:CMSInitiatingOccupancyFraction=75 //老年代内存使用率超过75%触发垃圾回收
-XX:+UseCMSInitiatingOccupancyOnly
ParNew:复制算法,将内存分为大小相等的两块,每次使用其中的一块一块用完时,将存活的对象复制到另一块。 CMS:使用标记-清除算法。整个过程分为四步:
- 初始标记:STW,标记GC Roots能关联到的对象,速度很快
- 并发标记:GC Roots Tracing过程。耗时。和用户线程一起执行(并行)
- 重新标记:STW,标记并发标记过程中程序运行导致标记变化的对象,时间比初始标记长,远比并发标记短
- 并发清除:耗时。和用户线程一起执行(并行)
G1
G1收集器的设计目标是取代CMS收集器,它同CMS相比,在以下方面表现的更出色:
- G1是一个有整理内存过程的垃圾收集器,不会产生很多内存碎片。
- G1的Stop The World(STW)更可控,G1在停顿时间上添加了预测机制,用户可以指定期望停顿时间。并基于用户指定的停顿时间来选择进行垃圾回收的区块数量。G1 采用增量回收的方式,每次回收一些区块,而不是整堆回收。
- G1 收集线程在标记阶段和应用程序线程并发执行,标记结束后,G1 也就知道哪些区块基本上是垃圾,存活对象极少,G1 会先从这些区块下手,因为从这些区块能很快释放得到很大的可用空间,这也是为什么 G1 被取名为 Garbage-First 的原因。
G1的各代存储地址是不连续的,每一代都使用了n个不连续的大小相同的Region,每个Region占有一块连续的虚拟内存地址。如下图所示:
Remembered Sets(Rset)
逻辑上说每个Region都有一个RSet,RSet记录了其他Region中的对象引用本Region中对象的关系。
Collection Set(CSet)
记录了GC要收集的Region集合,集合里的Region可以是任意年代的。
G1工作模式
- YoungGC年轻代收集
在分配一般对象(非巨型对象)时,当所有eden region使用达到最大阀值并且无法申请足够内存时,会触发一次YoungGC。每次younggc会回收所有Eden以及Survivor区,并且将存活对象复制到Old区以及另一部分的Survivor区。
- mixed gc
当越来越多的对象晋升到老年代old region时,为了避免堆内存被耗尽,虚拟机会触发一个混合的垃圾收集器,即mixed gc,该算法并不是一个old gc,除了回收整个young region,还会回收一部分的old region,这里需要注意:是一部分老年代,而不是全部老年代,可以选择哪些old region进行收集,从而可以对垃圾回收的耗时时间进行控制。
问题解决
通过指标数据,发现es集群存在新生代内存分配过小,导致young gc 频繁。 通过命令查看
jstat -gc pid 1000 1000
发现新生代内存仅分配了约1g,而老年代占到了29g。一种解决方案就是增大新生代,具体大小需要根据经验和调整后指标数据决定。
此外,调研发现,一些大的互联网公司,如美团,携程,es的垃圾回收器使用的都是G1。综上,直接替换es的垃圾回收器为G1。
-XX:+UseConcMarkSweepGC
-XX:CMSInitiatingOccupancyFraction=75
-XX:+UseCMSInitiatingOccupancyOnly
直接替换为
-XX:+UseG1GC
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)
最后
俗话说,好学者临池学书,不过网络时代,对于大多数的我们来说,我倒是觉得学习意识的觉醒很重要,这是开始学习的转折点,比如看到对自己方向发展有用的信息,先收藏一波是一波,比如如果你觉得我这篇文章ok,先点赞收藏一波。这样,等真的沉下心来学习,不至于被找资料分散了心神。慢慢来,先从点赞收藏做起,加油吧!
另外,给大家安排了一波学习面试资料:
文章来源:https://www.toymoban.com/news/detail-852379.html
以上就是本文的全部内容,希望对大家的面试有所帮助,祝大家早日升职加薪迎娶白富美走上人生巅峰!
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》,点击传送门即可获取!
早日升职加薪迎娶白富美走上人生巅峰!
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》,点击传送门即可获取!文章来源地址https://www.toymoban.com/news/detail-852379.html
到了这里,关于看完就能懂!ElasticSearch-垃圾回收器优化的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!