前言
在Java开发过程中,内存管理是一项至关重要的任务。作为开发者,我们时常会遇到一个让人头疼的问题——Java堆空间溢出(OutOfMemoryError,简称OOM)。当程序试图分配超出Java虚拟机(JVM)堆大小限制的内存时,就会抛出这个错误,导致程序崩溃或运行异常。
面对此类问题,定位其根源并不总是轻而易举。尤其在复杂的应用场景下,内存泄漏、对象生命周期管理不当或者对内存消耗估计不足等都可能成为触发OOM的原因。
本文主要讲解如何运用业界公认的性能分析工具JProfiler来精确地剖析和解决Java程序中的OOM问题。

Java虚拟机(JVM)的启动选项
示例:
-Xms20M -Xmx20M -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp
Java虚拟机(JVM)的启动选项,用于配置JVM的内存使用情况以及在发生OutOfMemoryError时的行为。以下是每个参数的含义:
-Xms20M: 这个参数设置JVM的初始堆内存大小为20MB。当Java虚拟机启动时,它会立即分配指定大小的内存作为堆空间,用于存储对象实例。-Xmx20M: 这个参数设置了JVM的最大堆内存大小也为20MB。这意味着在整个应用程序运行期间,堆内存不会超过这个限制。如果应用程序需要更多内存,但堆已满,则可能会抛出OutOfMemoryError异常。- -
XX:+HeapDumpOnOutOfMemoryError: 当启用此选项时,一旦JVM由于堆空间不足而抛出OutOfMemoryError异常,JVM将会生成一个堆转储文件(heap dump)。堆转储文件包含了JVM中所有对象的详细信息,这对于分析和找出导致内存溢出的具体原因非常有帮助。 -XX:HeapDumpPath=/tmp: 此参数指定了堆转储文件的生成路径。在这个示例中,当发生OutOfMemoryError时,堆转储文件会被保存到系统的临时目录 /tmp 下。开发者可以根据这个文件来排查和诊断内存问题。
模拟一个OOM的类
import java.util.LinkedList;
import java.util.List;
public class TestOOM {
public static class OOMObject {
byte[] b = new byte[1024];
}
/**
* -Xms20M -Xmx20M -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp
*/
public static void main(String[] args) {
List<OOMObject> list = new LinkedList<>();
while (true) {
list.add(new OOMObject());
}
}
}
测试
IDEA 添加虚拟机参数
进入Editor Configurations

点击Modify options

选择Add VM options

填写VM参数

粘贴进去后再Apply保存

最后直接运行

运行结果
java.lang.OutOfMemoryError: Java heap space

Dump内存文件

使用JProfiler来打开Dump文件

双击TestOOM$OOMObject

引用->选择为传入引用in coming refrences,然后点击确定

随机选择一个,点击右上方的显示到GC根的路径 Show Paths To GC Root
显示更多

定位到问题出现在代码的17行

JProfiler for Mac 下载
JProfiler Mac版下载 JProfiler for Mac(Java分析应用程序) v14.0.1 苹果电脑中文版 下载-脚本之家



















