前言
在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 苹果电脑中文版 下载-脚本之家