OOM signifie qu'il existe une vulnérabilité dans le programme, qui peut être causée par le code ou la configuration des paramètres JVM. Cet article explique aux lecteurs comment dépanner lorsqu'un processus Java déclenche le MOO.
On dit souvent qu'on est impressionné par l'environnement de production, et résoudre rapidement les problèmes est aussi un signe d'admiration
OOM signifie "Out Of Memory", ce qui signifie la mémoire est épuisée. Lorsque la JVM n'a pas assez de mémoire pour allouer de l'espace à l'objet et que le garbage collector n'a pas d'espace à recycler, il générera cette erreur
Pourquoi le MOO se produit-il généralement à cause de ces problèmes
Fuite de mémoire : la mémoire qui a été demandée n'est pas libérée, ce qui empêche la machine virtuelle d'utiliser à nouveau la mémoire. À ce moment, cette mémoire est divulguée. . Parce que le demandeur n'est plus utilisé, mais que la machine virtuelle ne peut pas être allouée à d'autres.
Dépassement de mémoire : La mémoire appliquée dépasse la taille de mémoire que la JVM peut fournir à ce moment-là, cela s'appelle un débordement.
La fuite de mémoire continue, et elle finira par déborder, les deux sont causalement liésjava.lang.OutOfMemoryError: PermGen space
Débordement de génération permanente Java7 (zone de méthode), utilisé pour stocker des données telles que des informations de classe, des constantes, des variables statiques et du code compilé par le compilateur juste à temps qui ont été chargés par la machine virtuelle. Chaque fois qu'une classe est chargée pour la première fois, les métadonnées seront stockées dans la génération permanente. Cela se produit généralement dans un grand nombre d'objets de classe ou de pages JSP, ou est provoqué par l'utilisation de la technologie de proxy dynamique CgLib.- XX:PermSize
et -XX:MaxPermSize
修改方法区大小
java.lang.StackOverflowError 虚拟机栈溢出,一般是由于程序中存在 死循环或者深度递归调用置过小也会出现溢出,可以通过Java8 将永久代变更为元空间,报错:java.lang.OutOfMemoryError: Metadata space,元空间内存不足默认进行动态扩展
-XX:PermSize
和-XX:MaxPermSize
修改方法区大小Java8 将永久代变更为元空间,报错:java.lang.OutOfMemoryError: Metadata space,元空间内存不足默认进行动态扩展
java.lang.StackOverflowError
虚拟机栈溢出,一般是由于程序中存在 死循环或者深度递归调用 造成的。如果栈大小设置过小也会出现溢出,可以通过
-Xss
设置栈的大小虚拟机抛出栈溢出错误,可以在日志中定位到错误的类、方法
java.lang.OutOfMemoryError: Java heap space
Java 堆内存溢出,溢出的原因一般由于 JVM 堆内存设置不合理或者内存泄漏导致
如果是内存泄漏,可以通过工具查看泄漏对象到 GC Roots 的引用链。掌握了泄漏对象的类型信息以及 GC Roots 引用链信息,就可以精准地定位出泄漏代码的位置
如果不存在内存泄漏,就是内存中的对象确实都还必须存活着,那就应该检查虚拟机的堆参数(-Xmx 与 -Xms),查看是否可以将虚拟机的内存调大些
小结:方法区和虚拟机栈的溢出场景不在本篇过多讨论,下面主要讲解常见的 Java 堆空间的 OOM 排查思路
查看 JVM 内存分布
假设我们 Java 应用 PID 为 15162,输入命令查看 JVM 内存分布
jmap -heap 15162