jvm性能调优实战 - 46堆区OOM解析

简介: jvm性能调优实战 - 46堆区OOM解析

Pre

之前的文章已经分析了Metaspace和栈内存两块内存区域发生内存溢出的原理,同时给出了一些较为常见的引发他们内存溢出的场景,一般只要代码上注意一些,不太容易引发那两块区域的内存溢出。

重点要来了,真正最容易引发内存溢出的,说白了就是平时我们系统创建出来的对象实在是太多了,最终就导致了系统的内存溢出!


从对象在Eden区分配开始讲起

如果要把这大量的对象是如何导致堆内存溢出的给讲清楚,那就得从系统运行,在Eden区创建对象开始讲起了。

咱们都知道,平时系统运行的时候一直不停的创建对象,然后大量的对象会填满Eden区

一旦Eden区满之后,就会触发一次Young GC,然后存活对象进入S区。

如下图所示


高并发场景下导致ygc后存活对象太多

当然因为各种各样的情况,一旦出现了高并发场景,导致ygc后很多请求还没处理完毕,存活对象太多,可能就在Survivor区域放不下了,此时就只能进入到老年代里去了,老年代很快就会放满了,如下图所示。

一旦老年代放满了就会触发Full GC,如下图所示。

我们假设ygc过后有一批存活对象,Survivor放不了,此时就等着要进入老年代里,然后老年代也满了,那么就得等着老年代进行CMS GC,必须回收掉一批对象,才能让年轻代里存活下来的一批对象进去。

但是呢,不幸的事情发生了,老年代GC过后,依然存活下来了很多的对象!如下图所示。

这个时候如果年轻代还有一批对象等着放进老年代,人家GC过后空间还是不足怎么办?

还能怎么办!只能是内存溢出了!如下图所示!

所以这个时候,老年代都已经塞满了,你还要往里面放东西,而且触发了Full GC回收了老年代还是没有足够内存空间,你坚持要放?那只能给你一个内存溢出的异常了!JVM跑不动了,崩溃掉。

这个就是典型的堆内存实在放不下过多对象的内存溢出的一个典型范例。


什么时候会发生堆内存的溢出?

发生堆内存溢出的原因其实总结下来,就一句话:

有限的内存中放了过多的对象,而且大多数都是存活的,此时即使GC过后还是大部分都存活,所以要继续放入更多对象已经不可能了,此时只能引发内存溢出问题。

所以一般来说发生内存溢出有两种主要的场景:

  • 系统承载高并发请求,因为请求量过大,导致大量对象都是存活的,所以要继续放入新的对象实在是不行了,此时就会引发OOM系统崩溃
  • 系统有内存泄漏的问题,就是莫名其妙弄了很多的对象,结果对象都是存活的,没有及时取消对他们的引用,导致触发GC还是无法回收,此时只能引发内存溢出,因为内存实在放不下更多对象了

因此总结起来,一般引发OOM,要不然是系统负载过高,要不然就是有内存泄漏的问题

这个OOM问题,一旦你的代码写的不太好,或者设计有缺陷,还是比较容易引发的,所以这个问题也是我们后面要重点分析的。


Case Demo

一旦要是系统负载过高,比如并发量过大,或者是数据量过大,或者是出现了内存泄漏的情况,很容易就导致JVM内存不够用了,就会堆内存溢出,然后系统崩溃。 所以今天就体验一下堆内存溢出的场景。

Review 堆内存溢出的一个典型场景

首先还是来一张完整的JVM运行原理图,里面包含了对象的分配,GC的触发,对象的转移,各个环节如何触发内存溢出的,大家一定要牢记这张图。

接着我们就来回顾一下一个典型的堆内存溢出的场景:

假设现在系统负载很高,不停的运转和工作,不停的创建对象塞入内存里,刚开始是塞入哪里的?

当然是年轻代的Eden区了,如下图红圈所示。

但是因为系统负载实在太高了,很快就把Eden区塞满了,这个时候触发ygc

但是ygc的时候发现不对劲,因为似乎Eden区里还有很多的对象都是存活的,而且survivor区域根本放不下,这个时候只能把存活下来的大批对象放入老年代中去,如下图红圈处。

就这么来几次ygc之后,每次ygc后都有大批对象进入老年代,老年代很快就会塞满了,而且最重要的是这里的对象还大多都是存活的。

所以接下来一次ygc后又要转移一大批对象进入老年代,先触发full gc,但是full gc之后老年代里还是塞满了对象,如下图红圈所示。

这个时候ygc后存活下来的对象哪怕在full gc之后还是无法放入老年代中,此时就直接报出堆内存溢出了,如下图红圈所示。

所以堆内存溢出的场景就是这样子,非常的简单 。


模拟Code

代码很简单,就是在一个while循环里不停的创建对象,而且对象全部都是放在List里面被引用的,也就是不能被回收。

大家试想一下,如果你不停的创建对象,Eden区满了,他们全部存活会全部转移到老年代,反复几次之后老年代满了。

然后Eden区再次满了,ygc后存活对象再次进入老年代,此时老年代先full gc,但是回收不了任何对象,因此ygc后的存活对象就一定是无法进入老年代的。

所以我们用下面的JVM参数来运行一下代码:-Xms10m -Xmx10m,我们限制了堆内存大小总共就只有10m,这样可以尽快触发堆内存的溢出。

我们在控制台打印的信息中可以看到如下的信息:

当前创建了第360145个对象

Exception in thread “main” java.lang.OutOfMemoryError: Java heap space

所以从这里就可以看到,在10M的堆内存中,用最简单的Object对象搞到老年代被塞满大概需要36万个对象。然后堆内存实在放不下任何其他对象,此时就会OutOfMemory了,而且告诉了你是Java heap space,也就是堆空间发生了内存溢出的。


小结

可以看到堆内存是如何溢出的,以及溢出的时候回看到什么样的异常信息。


相关文章
|
2月前
|
安全 Oracle Java
JAVA高级开发必备·卓伊凡详细JDK、JRE、JVM与Java生态深度解析-形象比喻系统理解-优雅草卓伊凡
JAVA高级开发必备·卓伊凡详细JDK、JRE、JVM与Java生态深度解析-形象比喻系统理解-优雅草卓伊凡
201 0
JAVA高级开发必备·卓伊凡详细JDK、JRE、JVM与Java生态深度解析-形象比喻系统理解-优雅草卓伊凡
|
7月前
|
人工智能 API 开发者
HarmonyOS Next~鸿蒙应用框架开发实战:Ability Kit与Accessibility Kit深度解析
本书深入解析HarmonyOS应用框架开发,聚焦Ability Kit与Accessibility Kit两大核心组件。Ability Kit通过FA/PA双引擎架构实现跨设备协同,支持分布式能力开发;Accessibility Kit提供无障碍服务构建方案,优化用户体验。内容涵盖设计理念、实践案例、调试优化及未来演进方向,助力开发者打造高效、包容的分布式应用,体现HarmonyOS生态价值。
332 27
|
7月前
|
数据采集 JSON 数据可视化
JSON数据解析实战:从嵌套结构到结构化表格
在信息爆炸的时代,从杂乱数据中提取精准知识图谱是数据侦探的挑战。本文以Google Scholar为例,解析嵌套JSON数据,提取文献信息并转换为结构化表格,通过Graphviz制作技术关系图谱,揭示文献间的隐秘联系。代码涵盖代理IP、请求头设置、JSON解析及可视化,提供完整实战案例。
441 4
JSON数据解析实战:从嵌套结构到结构化表格
|
7月前
|
数据采集 机器学习/深度学习 存储
可穿戴设备如何重塑医疗健康:技术解析与应用实战
可穿戴设备如何重塑医疗健康:技术解析与应用实战
242 4
|
7月前
|
机器学习/深度学习 人工智能 Java
Java机器学习实战:基于DJL框架的手写数字识别全解析
在人工智能蓬勃发展的今天,Python凭借丰富的生态库(如TensorFlow、PyTorch)成为AI开发的首选语言。但Java作为企业级应用的基石,其在生产环境部署、性能优化和工程化方面的优势不容忽视。DJL(Deep Java Library)的出现完美填补了Java在深度学习领域的空白,它提供了一套统一的API,允许开发者无缝对接主流深度学习框架,将AI模型高效部署到Java生态中。本文将通过手写数字识别的完整流程,深入解析DJL框架的核心机制与应用实践。
379 3
|
9月前
|
运维 Shell 数据库
Python执行Shell命令并获取结果:深入解析与实战
通过以上内容,开发者可以在实际项目中灵活应用Python执行Shell命令,实现各种自动化任务,提高开发和运维效率。
249 20
|
7月前
|
缓存 监控 搜索推荐
【实战解析】smallredbook.item_get_video API:小红书视频数据获取与电商应用指南
本文介绍小红书官方API——`smallredbook.item_get_video`的功能与使用方法。该接口可获取笔记视频详情,包括无水印直链、封面图、时长、文本描述、标签及互动数据等,并支持电商场景分析。调用需提供`key`、`secret`和`num_iid`参数,返回字段涵盖视频链接、标题、标签及用户信息等。同时,文章提供了电商实战技巧,如竞品监控与个性化推荐,并列出合规注意事项及替代方案对比。最后解答了常见问题,如笔记ID获取与视频链接时效性等。
|
9月前
|
供应链 搜索推荐 API
深度解析1688 API对电商的影响与实战应用
在全球电子商务迅猛发展的背景下,1688作为知名的B2B电商平台,为中小企业提供商品批发、分销、供应链管理等一站式服务,并通过开放的API接口,为开发者和电商企业提供数据资源和功能支持。本文将深入解析1688 API的功能(如商品搜索、详情、订单管理等)、应用场景(如商品展示、搜索优化、交易管理和用户行为分析)、收益分析(如流量增长、销售提升、库存优化和成本降低)及实际案例,帮助电商从业者提升运营效率和商业收益。
434 20
|
8月前
|
数据可视化 测试技术 API
GraphQL开发工具选型指南:Apipost高效调试与文档生成实战解析
本文深入解析了GraphQL开发工具Apipost在高效调试与文档生成方面的优势,对比同类工具Apifox,突出其可视化界面、实时调试及自动化文档生成等特性。Apipost通过智能代码补全、错误提示等功能简化复杂Query编写,支持一键生成标准化文档,显著提升开发效率和团队协作效果,尤其适合中大型团队应对复杂业务场景。
|
9月前
|
数据采集 XML API
深入解析BeautifulSoup:从sohu.com视频页面提取关键信息的实战技巧
深入解析BeautifulSoup:从sohu.com视频页面提取关键信息的实战技巧

热门文章

最新文章

推荐镜像

更多
  • DNS