JVM内存溢出(一)之排查初体验

一、构建环境

1.1创建测试类 Test.java文件

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

/**
 * @author steven
 * @Description
 * @date 2023/7/14 13:59
 */
public class Test {

    /**
     * 实现,向集合中添加100万个字符串,每个字符串由100个UUID组成
     */
    public static void main(String[] args) {
        List list = new ArrayList<>();
        for (int i = 0; i < 1000000; i++) {
            String str = "";
            for (int j = 0; j < 1000; j++) {
                str += UUID.randomUUID().toString();
            }
            list.add(str);
        }
        System.out.println("ok");
    }

}

1.2 运行时jvm参数如下参数:

-Xms8m
-Xmx8m
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=D:\software\JavaDevelopment\javatool\check_tool\dump\
-XX:+PrintGCDetails
-Xloggc:D:\software\JavaDevelopment\javatool\check_tool\dump\gc.log

我是用的idea开发工具截图如下:

JVM内存溢出(一)之排查初体验_第1张图片

1.3执行测试类代码,出现以下日志,发生了内存溢出。

java.lang.OutOfMemoryError: Java heap space
Dumping heap to D:\software\JavaDevelopment\javatool\check_tool\dump\java_pid18300.hprof ...
Heap dump file created [8129976 bytes in 0.015 secs]
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
	at java.util.Arrays.copyOf(Arrays.java:3332)
	at java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:124)
	at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:448)
	at java.lang.StringBuilder.append(StringBuilder.java:136)
	at Test.main(Test.java:20)
Disconnected from the target VM, address: '127.0.0.1:58380', transport: 'socket'

Process finished with exit code 1

二、分析日志

日志分析为三部分:控制台日志、dump文件和GC日志。

2.1控制台日志(如1.3中出现的日志)

java.lang.OutOfMemoryError: Java heap space
Dumping heap to D:\software\JavaDevelopment\javatool\check_tool\dump\java_pid18300.hprof ...
Heap dump file created [8129976 bytes in 0.015 secs]
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
	at java.util.Arrays.copyOf(Arrays.java:3332)
	at java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:124)
	at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:448)
	at java.lang.StringBuilder.append(StringBuilder.java:136)
	at Test.main(Test.java:20)
Disconnected from the target VM, address: '127.0.0.1:58380', transport: 'socket'

Process finished with exit code 1

 堆内存溢出:Java heap space;

 发生在数组扩容时期: Arrays.copyOf();

 发生的业务方法 Test类20行处: at Test.main(Test.java:20)

2.1dump文件

2.1.1工具

本人推荐jvisualvm.exe 和 jprofiler 两款分析工具,其中jvisualvm在jdk中bin目录中可以找到

JVM内存溢出(一)之排查初体验_第2张图片

使用jvisualvm打开生成的dump文件 java_pid20360.hprof

JVM内存溢出(一)之排查初体验_第3张图片

 点击导致 OutOfMemoryError 异常错误的线程 JVM内存溢出(一)之排查初体验_第4张图片

  jprofiler 官方可以下载 Java Profiler - JProfiler

2.2分析(jvisualvm)

dump文件内容如下

 
"JDWP Event Helper Thread" daemon prio=10 tid=7 RUNNABLE

  
"Finalizer" daemon prio=8 tid=3 WAITING
    at java.lang.Object.wait(Native Method)
    at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143)
    at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:164)
       Local Variable: java.lang.ref.ReferenceQueue#15
    at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:209)
       Local Variable: java.lang.System$2#1

  
"Signal Dispatcher" daemon prio=9 tid=4 RUNNABLE

  
"main" prio=5 tid=1 RUNNABLE
    at java.lang.OutOfMemoryError.(OutOfMemoryError.java:48)
    at java.util.Arrays.copyOf(Arrays.java:3332)
       Local Variable: char[]#20
    at java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:124)
    at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:448)
    at java.lang.StringBuilder.append(StringBuilder.java:136)
       Local Variable: java.lang.String#19
       Local Variable: java.lang.StringBuilder#1
    at Test.main(Test.java:20)
       Local Variable: java.lang.String[]#118
       Local Variable: java.util.ArrayList#23
       Local Variable: java.lang.String#18

  
"JDWP Transport Listener: dt_socket" daemon prio=10 tid=6 RUNNABLE

  
"JDWP Command Reader" daemon prio=10 tid=8 RUNNABLE

  
"Attach Listener" daemon prio=5 tid=5 RUNNABLE

  
"Reference Handler" daemon prio=10 tid=2 WAITING
    at java.lang.Object.wait(Native Method)
    at java.lang.Object.wait(Object.java:502)
    at java.lang.ref.Reference.tryHandlePending(Reference.java:191)
    at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)

可知是数组扩容是出现的出现堆溢出Arrays.copyOf(Arrays.java:3332)

业务行Test类20行:Test.main(Test.java:20)

JVM内存溢出(一)之排查初体验_第5张图片

3.3GC日志

JVM内存溢出(一)之排查初体验_第6张图片

你可能感兴趣的:(JVM,jvm,java,开发语言)