当前位置:首页 > 公众号精选 > 架构师社区
[导读]垃圾回收器老哥:你这样疯狂的嚯嚯对象,有考虑过我的感受吗?

“对象”的一生

像往常一样,早上10点到了公司,赵小八打开电脑收到了PM前一天晚上发来的推荐系统新需求,内心一万只草泥马飘过,思索了半天,打开IDEA开始了“愉快的”new对象之旅。

垃圾回收器老哥:你这样疯狂的嚯嚯对象,有考虑过我的感受吗?

赵小八:你谁啊?我new对象干你啥事?

垃圾回收器老哥:年轻人火气别这么大,既然你这么说那请耗子尾汁。

赵小八:呵,你哥我是被吓大的

垃圾回收器老哥:年轻人不讲武德...

没两天,小八翘着尾巴给PM说,功能上线了,刚没一会儿PM骂骂咧咧的找来了,这tm为啥有时候能出来内容有时候出不来啊,小八菊花一紧赶紧查起了问题,先搂监控接口平均耗时从200ms涨到了300ms,小八心想,我不过就多new了几个对象,怎么tm的影响会这么大,同时DBA同学反馈资源监控正常,看来只能搂业务日志看看了,可是业务日志也并没有什么问题,难道GC有问题?果不其然,GC日志像疯了一样的刷日志。小八赶紧让运维紧急回滚线上代码并dump了一份GC日志分析了起来。

现场代码复原

上面这段代码是一个简化版的用户推荐系统,真实情况下加载需要加载的物料除机器学习物料、商业物料外,还有其他各种例如:运营物料、曝光物料、关系物料等等。

当一个真实用户请求过来之后,上面提到的这些物料就需要全部被加载进来。对象首先从新生代中被创建出来,接着经过一段时间GC后,最后存活下来的对象成功晋级到老年代,那么对象是在什么情况下成功晋级到老年代的呢?

case1:对象经历15次GC

  1. 小八疯狂的new对象,此时新创建的都被分配到Eden区,如下图:

  1. 小八继续疯狂new对象,直到jvm老哥的Eden区放不下更多的对象了,于是触发了一次youngGC,通过这次youngGC之后,只有Context1对象被回收,剩余存活对象进入到了Survivor1里面,如下图:
  1. 第一次youngGC结束后,小八又开始了new对象的神操作
  1. 没一会儿,jvm又开始了youngGC,此时Eden区和Survivor1里面的存活对象全部移入到Survivor2中,剩余垃圾对象被回收。

  1. 就这样反反复复经历了15次youngGC的折腾,还没有被垃圾回收掉的对象最终进入了Old区

case2:动态年龄判断

  1. 小八疯狂的new对象
  1. 小八继续疯狂new对象,直到jvm老哥的Enden区放不下更对的对象了,于是触发了一次youngGC

经过此次youngGC后,剩余存活对象内存占用大小超过了survivor1区大小的50%,比如:survivor1区大小为50M,而进入到survivor1区的存活对象大小为30M,此时会将当前存活时间最久的对象直接晋升到老年代(存活时间:经历过GC次数最多的对象),此时Context2对象和Context3对象进入到老年代

case3:空间担保机制

小八上线的用户推荐系统,JVM内存的划分情况为:整个堆大小为5G,其中老年代2.5G,新生代2.5G,其中新生代中Eden区:Survivor区=8:2,即Eden区大小为2G,两个Survivor区大小各为250M。

在晚高峰的时候一下子涌入1000人查看推荐列表,一个用户消耗的JVM内存达到了500kb,那么在一秒内就消耗了500M,那么就意味着4秒钟就会产生一次youngGC,假设每次GC后剩余的存活对象为300M,由于300M大小的存活对象无法在survivor区中存放下,此时就触发了空间担保机制。

  1. 小八疯狂的new对象
  1. 直到发生第一次youngGC,但是一次youngGC后剩余的存活的对象大小Survivor区无法容纳下,此时所有存活对象会直接进入到Old区

在新生代没有足够的内存存储新产生的对象时,老年代会判断自己的区域剩余的内存空间是否能够放得下历代youngGC后剩余存活对象(假设历代youngGC剩余存活对象大小为300M),假设此时老年代还有1G大小的可用内存,那么此次youngGC后剩余的存活对象将直接进入到老年代;假设此时老年代剩余可用内存大小为200M,那么就会触发一次OldGC,OldGC完成后产生的空闲空间大于300M,此时会将新生代的存活对象放入老年代,如果OldGC后剩余的空闲空间小于300M,那么不好意思,就会抛出OOM了。

一图总结Java对象流转情况

上图便是整个Java对象一生经历的流程,流程图相对比较复杂一点,从上往下对照前面讲到的三种情况,相信还是比较容易理解的。

当然图中没有画图新生代触发OOM的情况,可以试想一下Eden区在什么时候会触发OOM?答案在下篇文章给出。

总结

通过一个实际线上案例,讲述了Java对象在不同情况下在JVM中经历的一生。通过本文大家可以尝试将该流程套用到自己公司的项目里面,来分析自己负责的项目是否有类似的问题,或者通过本篇文章来尝试优化自己的项目。另外本文的内容可能会有某些地方讲解的不合适,欢迎有问题的朋友和我私聊探讨。

在上篇文章中留了一个问卷调查,结论如下:总投票人数7人,其中最想了解的技术是SpringCloud,最喜欢的分享方式是图文结合。虽然投票人数比较少,但我相信投票的真实性,后续我会以这个结论为导向,分享更多实用的内容给大家。

打个小广告,年后大家有换个工作氛围的朋友或者身边有想法的朋友,快手研发、运维、产品、运营全部岗位都有你想要的坑位,各种新业务发展速度快,机会多多,面试流程反馈速度超快,欢迎朋友们自荐或者推荐朋友来一起做点有意义的事。




		
		
		
		

免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

Java是一种广泛应用于软件开发的编程语言,它具有跨平台、面向对象和高度可靠性的特点。在嵌入式系统设计中,Java也有着广泛的应用方案。本文将详细介绍Java在嵌入式系统设计中的应用方案,并分析其优势和挑战。

关键字: Java 软件开发 编程语言

嵌入式系统是指集成了计算机软硬件的特定系统,通常用于控制和监控设备、机器和系统。Java作为一种通用的编程语言,在嵌入式系统的开发中也有广泛的应用。下面将介绍一些嵌入式系统中Java的开发工具和解决方案。

关键字: 嵌入式 计算机 Java

Java语言是一种面向对象的编程语言,由Sun Microsystems(现在是Oracle Corporation)于1995年推出。Java具有跨平台性和可移植性的特点,广泛用于开发各种应用程序,包括嵌入式系统、移动...

关键字: Java 编程语言 互联网

12月7日消息,近日,Java全球管理组织JCP披露了最高执行委员会(JCP-EC)新成员名单,作为唯一中国代表,阿里巴巴再次连任,任期两年。这是阿里连续三次入选JCP最高管理席位,代表着中国技术公司长期参与Java全球...

关键字: 阿里云 Java

经常有一些小伙伴来咨询二哥培训机构方面的问题,通常情况下,如果自学能力可以的话,我是建议通过《Java 程序员进阶之路》配上 B 站的教学视频,先把 Java 后端四大件学扎实(Java 基础、Spring Boot、R...

关键字: Java 培训机构 算法

Java是一门面向对象的编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承、指针等概念,因此Java语言具有功能强大和简单易用两个特征。Java语言作为静态面向对象编程语言的代表,极好地实现了面向...

关键字: Java C++

作为一个 PHP 转 Java 的业务开发,经常对自己的 Java 基础是否扎实有个问号。实际业务上由于基本上都是 CURD,并没遇到什么困难,但越是这样有时候心里就越慌。

关键字: PHP Java

昨天,二哥的编程星球里的一位球友问我能不能给他解释一下@SpringBootApplication注解是什么意思,还有 Spring Boot 的运行原理,于是我就带着他扒拉了一下这个注解的源码,还有SpringAppl...

关键字: Java Spring Boot

摘要:设计了一种基于Java和selenium的自动化操作工具,利用selenium开源自动化测试框架建立企业信息系统自动化执行的解决方案,着重对比自动化工具和手工操作的差异。通过使用工具和人工操作的对比试验,证明这种工...

关键字: 自动化操作工具 selenium Java

摘 要 :为了节约油气生产的建设投资成本,提高劳动生产效率,中石油建设了规范、统一的油气生产物联网系统。文中介绍了油气生产物联网管理子系统的功能设计、系统数据架构及数据处理。该系统的持续完善与深入应用必将为转变油气田生产...

关键字: 油气生产 物联网 管理 Java 生产效率 子系统
关闭
关闭