内存不足(OOM)是操作系统或程序无法再申请内存的一种状态。通常是因为所有可用内存(包括磁盘交换空间)都已分配。官方对OOM的解释是:了解OutOfMemoryErrorException,根据HeapDump性能社区独家讲师的总结,常见的OOM有以下10种(OOMKiller是操作系统层面的概念)。那些年我们遇到的OOM——开篇推荐共宇大佬第一期视频教程《那些年我们遇到的OOM》。在这门课程中,共宇重新梳理了大众对OOM的理解和认知,简单明了,简明扼要地介绍了Java虚拟机的内存分布,并对本系列课程中出现的10种OOM进行了简要解读。观看此视频课程可以让您对OOM有一个整体的了解。不同类型的OOM的原因是什么?如何分析和解决生产环境中的OOM?有哪些好的定位工具?本期HeapDump性能社区OOM专篇共收录20篇相关文章,包括高手经验总结、高手源码分析、海量实战案例。希望大家喜欢阅读。Part1:Theory1.JVM中OOM的8个原因及解决方案作者:詹小浪本文简要介绍了OOM的8个原因及其解决方案,包括分析方法、排查命令、调参思路等。2.一篇解释什么是oom,为什么会出现oom,oom的类型和常见解决方法作者:G.Shine本文首发于博客园G.Shine2012年的一篇文章,对OOM问题最简单的总结,以及最容易理解的。虚拟机所涉及的技术或工具往往需要考虑到虚拟机的规格和不同的虚拟机实现。尤其是在调优虚拟机的时候,往往需要在某些方面考虑虚拟机的实现策略。例如,不同的虚拟机有不同的垃圾回收算法,这直接影响到虚拟机的参数。优化虚拟机性能的设置。对于JVM运行时的分析诊断,需要掌握基本的分析方法。具体情况,利用虚拟机的原理具体分析。可以在HeapDump性能社区阅读更多JVM相关文章,或者使用社区的XXFOX工具:https://opts.console.heapdump.cn/3。JVM源码分析OutOfMemoryError完整解读作者:你fakeOutOfMemoryError,你说的是java.lang.OutOfMemoryError,是JDK自带的异常。顾名思义,就是关于内存溢出的。当我们的系统内存严重不足时会抛出这个异常(PS:注意这是一个Error,不是Exception,所以我们要捕获异常的时候要注意),这个Exception常见且常见,也很少见,但作为一名Java程序员,您至少应该听说过它们。如果你对jvm不是很熟悉,或者对异常OutOfMemoryError没有深入了解,这篇文章肯定还是能给你带来一些惊喜。通过这篇文章,你至少可以了解到以下几点:OutOfMemoryError会被加载吗?什么时候会抛出OutOfMemoryError?会产生无数的OutOfMemoryError实例吗?如何分析此类异常4、Java中使用软引用和弱引用避免oom作者:矩阵海子本文首先介绍了强引用、软引用、弱引用、幻引用相关的概念,然后讲解了如何使用软引用referenceswithexamples和weakreferencestoavoidOOM:如果有一个应用程序需要读取大量的本地图片,如果每次都从硬盘读取图片,会严重影响性能,但是如果都是加载到内存中,可能会导致内存丢失。溢出,此时使用软引用可以解决这个问题。设计思路是:用一个HashMap来保存图片的路径和对应图片对象关联的软引用的映射关系。当内存不足时,JVM会自动回收这些缓存的图片对象占用的空间,从而有效避免了OOM问题。在Android开发中,经常用于下载大量图片。5、OOM系列之八:java.lang.OutOfMemoryError:Killprocessorsacrificchild本文来自plumbr官网。Plumbr是一种常用的JVM监控工具。官网有关于oom和gc的完整文章。我只是为了翻译而复制它们。此处文章为完结篇。PartII:实战6.经历了一次线上CPU100%和应用OOM排查及解决过程登录时发现服务OOM,然后使用Top命令查看系统中各个进程的资源使用情况,发现有一个进程的CPU占用率达到了300%,于是查询了该进程下所有线程的CPU占用率,并保存了堆栈数据。根据上述操作,在获取到问题服务的GC信息、线程堆栈、堆快照等数据后,使用HeapDump社区提供的XElephant进行分析,进一步发现是InMemoryReporterMetrics导致的OOM是问题服务取决于zipkin版本较低,升级它解决了问题。虽然本文的描述和解决方案都不是罕见的疑难杂症,但排查思路清晰,流程完整。还推荐了故障排除工具,适合初学者阅读学习。7、容器化springboot程序OOM问题探索作者:夏梦笔者被告知容器化java程序每运行一段时间就会出现OOM问题。首先,日志没有发现异常;然后,通过JStat查看GC情况,发现情况正常但是ByteBuffer对象占用最高(异常点1);然后通过JStack查看线程快照情况,发现创建的kafka生产者过多(异常点2);最后,通过写一个demo程序来验证猜想,确定问题是业务代码循环创建Producer对象引起的。排查流程清晰,工具运用熟练,验证过程快速准确。8.真正的在线OOM问题定位。作者:王正。OutOfMemoryError发生在笔者负责的系统生产环境中。伴随这个问题而来的还有一堆FullGC、100%CPU、频繁关机重启等,严重影响业务的推广和使用。这样的问题一般很难处理。本文梳理了该问题的发生以及定位和解决过程,为后续处理类似问题提供参考指导。9、Nginx百万长连接压测OOM排查分析作者:挖坑的张师傅在百万长连接压测中,笔者发现有4台32C和128G的Nginx频繁出现OOM。发现问题后,首先查看了Nginx与客户端的网络连接状态。首先怀疑是jmeter客户端处理能力有限,很多消息都堆积在中转的nginx,于是把nginx的内存dump出来查看,确定是缓存的原因。大量消息导致内存增加;然后查看Nginx的参数配置,发现proxy\_buffers的值设置的特别大;然后模拟上下行收发速度不一致对Nginx内存占用的影响。最后将proxy\_buffering设置为off,减小proxy\_buffer\_size的值后,Nginx的内存就稳定了。作者排错思路清晰,工具使用和调参非常熟练,对底层原理和源码有深刻理解。无论是经验还是态度,都非常值得学习和借鉴。10、一次OOMcrash的处理过程作者:图图奇笔者这次遇到的故障是典型的内存不足导致OOM错误的情况。从系统状态和日常监控,以及系统日志中的错误报告,都能找到踪迹,但由于缺乏重视,没有引起足够的重视,最终导致崩溃。另外mrtg运行出错,发送大量垃圾邮件,导致amavisd调用clamscan卡住,也让系统不堪重负。对于类似问题,需要对系统进行监控,分析原因,再采取有效措施。同时,管理员也不能忽视日常维护工作,以免出现无法挽回的故障。11、为什么容器内存占用居高不下,频频OOMKubernetes下半年,业务服务变少,偶尔被运维阶段性惊醒,问“为什么你的服务内存占用太高,请速查。”这个时候大家还在为新业务冲刺,猜测可能是业务代码的问题,但是并没有调整代码去尝试解决。做Kubernetes的第二年,业务服务逐渐增多,容器限制也普遍提高。一些业务服务以内存怪物的形式出现。因此,如果没有限制,服务占用过多会导致驱逐,所以反馈语言也会发生变化。变成了:“为什么你的服务内存占用这么高,老是OOMKilled,赶紧查查。”经过长时间排查:怀疑业务代码(PProf)-怀疑其他代码(PProf)-怀疑GoRuntime-怀疑工具-怀疑环境,终于找到原因并给出了解决方案。12、为什么容器内存占用率居高不下,频繁OOM(续)作者:建宇经过内部讨论,由于各种原因(例如:Linux、Kubernetes太低),我们选择升级Linux版本,这是CentOS8,这样它的内核版本会达到4.x(cgroup变强了很多,4.5cgroupv2已经可以GA了),相关问题已经修复,通过同步设置cgroup可以解决/避免相关问题.memory=nokmem。在写这篇文章的时候,我们可以看到kmemaccounting的很多问题已经被修复或者提上日程,这为本次调研提供了相当大的便利。确定问题后,根据cgroupleakalong排查,基本上可以看到前辈经历过的很多“挣扎”。如果您有兴趣,还可以按照参考资料提供的链接进行更高级和深入的了解。但实际上,无论是哪个版本的Linux内核,都或多或少存在问题,需要做好心理准备,否则就会遇到“没有容器就好了”的窘境,并且找出问题会更麻烦。13.追根究底——回忆一次OOM测试引起的电脑雪崩的思考作者:码海作者通过一次OOM测试提出了三个值得思考的问题:while(true)和cpuload的关系?为什么发生OOM后,Ctrl+C不能停止Java进程?为什么主线程OOM后Java进程不停止运行?然后一一验证,并提醒读者,看到书上的demo最好亲自尝试一下,说不定会有新的发现呢!纸上谈兵的成果总是肤浅的,我知道这件事必须要做。遇到问题,最好是奋发图强,这样才会收获很多,进步很快!14.震惊!在线的四台机器同时OOM,怎么回事?作者:码海本文通过四台在线机器同时OOM现象,详细分析定位问题原因。可见,我们在应用某个库的时候,首先要对这个库有充分的了解(上面提到的HttpClient创建单例显然是个问题),其次,必要的网络知识还是需要的,所以要成为一名合格的程序员,不仅要懂语言本身,还要涉猎网络、数据库等,对故障排除和性能调优会有很大帮助。同样,完善的监控非常重要。通过触发一定的阈值进行预警,可以将问题扼杀在萌芽状态!15.实战:OOM后如何分析解决?作者:jasonGeng88刚开始排查内存泄漏的时候,常常有点不知所措。我们需要有正确的方法和手段,再加上有用的工具,这样才能处理问题游刃有余。当然,JAVA内存的基础知识也是必不可少的。这是定位问题的关键。否则,即使工具告诉你有问题,你也无法定位原因。16、导致程序OOM的因素。夜深人静,程序的OOM异常跟踪作者:图图奇作为一名Java程序员,除了享受着垃圾回收机制带来的便利之外,也深受OOM(OutOfMemory)折磨的困惑和困扰。笔者故障定位发现的N-multipleOOM问题,大多是由以下三类引起的:1.非托管线程池滥用;1.对特殊场景考虑不够(比如单线程处理复杂业务,环境冲击+多设备下积压任务激增)17.FastJson和堆内存溢出'血案'作者:landon30场景:QA同学反映无法登录服务器查看流程:日志级别——JVM命令级别——专业工具级别分析流程:观察数据——尝试再重试——无路可走——源码跟踪——问题初步总结解决问题:为什么成本这么大?刚才我们基本确定错误模式的反序列化会导致cost字段越来越大,所以不会是上亿次吧?这个我大概查了一下代码,很有可能是好友推荐模块和相关模块。相关代码需要对离线图片进行更频繁的反序列化或者类似心跳的业务处理。解决方法很简单,序列化fastjson的时候记得加上IgnoreNonFieldGetter即可。18.一次Java进程OOM的调查与分析(glibc篇)作者:张师傅,在挖坑的时候遇到了glibc引起的内存回收问题。查找原因和实验的过程比较有趣,主要涉及以下内容:Linuxglibc中典型的大64M内存区域问题glibc的内存分配器ptmalloc2的底层原理如何编写自定义mallochook动态链接的内存分配原理librarysoglibc(Arena,Chunkstructure,bins等)malloc_trim对realmemoryrecovery的影响gdb堆调试工具使用的jemalloclibrary介绍及应用19.垃圾回收-实战作者:geekofastest本文介绍JVM参数和GC详细的日志,OOM的原因和相应的调试工具。相信读者应该已经掌握了基本的MAT、jvisualvm工具来排查问题,但是这些工具的介绍只是说了一些粗浅的,大家可以多了解一下相应工具的一些高级技巧,对自己排查问题大有裨益!大家可以通过文中的例子进行实验,修改参数,看看会出现什么神奇的现象,自己动手,为排查问题扫清障碍。20.使用XPocket插件JConsole排查在线OOM异常作者:Jiumo堆外的其他区域。JConsole可以查看Java进程的内存使用情况,尤其是在查看过程中,需要多次打印,比较数值才能发现问题。如果想进一步定位到代码层面的问题,还可以借助XPocket中的其他插件进行辅助定位。OOM问题有很多种。实际业务场景中,环境比较复杂,需要具体问题具体分析。这就需要对各种OOM的原理有足够的了解和熟悉。本文收集了大佬总结、源码分析、大量排查案例等20篇文章,旨在帮助读者补充相关知识点,从理论和实战中学习方法,从经验中学习,避免踩坑。Part3:考试篇看到这里,你已经超越了很多人~要不要来参加考试?看你学习多好!小礼物:首次答题得分90分以上,并在社区以上文章下方留言者,将获得HeapDump性能社区OOM勋章一枚(每半个月统计一次)!竞猜链接:https://ks.wjx.top/vj/trlUZ7d.aspx奖品数量有限,先到先得~
