内存溢出
注意内存溢出不是内存泄漏!!这里主要是介绍如何用jdk自带的jmap工具导出进程堆空间快照。
-
内存溢出:
Out Of Memory,是指申请的堆内存空间不够用了,比如:你申请了10M空间,但是你要放12M的东西进去; -
内存泄漏:
Memory Leak,是指你的堆空间一直有对象占着那片空间,不能被GC清理掉;你还要放对象进去,还在向堆申请放对象的空间,此时就会报 Memory Leak;还在被引用,但是没有被使用了,jvm一直没有去清理。 -
这里主要演示内存溢出 : 模拟代码
package com.distributed.lock.utils;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
1. -Xms30m -Xmx=30m -XX:SurvivorRatio=8 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=d:\99.hprof
2. 模拟OOM
*/
public class OOMTest {
public static void main(String[] args) {
System.out.println("演示开始:>>>>>>>>>>>>>>>>>>>>>>>>>>>");
//先向堆空间申请一块内存区域,区域的大小默认是ArrayList的长度
List<int[]> arr = new ArrayList<>(10);
for (int i = 0; i < 10000; i++) {
//不断的新创建对象,对象大小为1M
int[] ints = new int[1024*1024];
//一直往ArrayList集合添加
arr.add(ints);
try {
TimeUnit.MILLISECONDS.sleep(100);
} catch (Exception e) {
e.printStackTrace();
}
}
System.out.println("演示结束:>>>>>>>>>>>>>>>>>>>>>>>>>>>");
}
}
-
异常信息 :
-
导出堆空间快照(dump):
先看jmap语法规则:
C:\Windows\system32>jmap -help
Usage: //语法规则,使用方式
jmap [option] <pid>
(to connect to running process)
jmap [option] <executable <core>
(to connect to a core file)
jmap [option] [server_id@]<remote server IP or hostname>
(to connect to remote debug server)
where <option> is one of: //参数选项介绍
<none> to print same info as Solaris pmap
-heap to print java heap summary
-histo[:live] to print histogram of java object heap; if the "live"
suboption is specified, only count live objects //只是当前时间节点活着的对象
-clstats to print class loader statistics
-finalizerinfo to print information on objects awaiting finalization
-dump:<dump-options> to dump java heap in hprof binary format
dump-options:
live dump only live objects; if not specified,
all objects in the heap are dumped.
format=b binary format
file=<file> dump heap to <file>
Example: jmap -dump:live,format=b,file=heap.bin <pid>
-F force. Use with -dump:<dump-options> <pid> or -histo
to force a heap dump or histogram when <pid> does not
respond. The "live" suboption is not supported
in this mode.
-h | -help to print this help message
-J<flag> to pass <flag> directly to the runtime system
将堆空间信息以标准格式导出到文件:
jmap -dump:format=b,file=d:\7.hprof 14876
将堆空间存活对象的信息以标准格式导出到文件:
jmap -dump:live,format=b,file=d:\7.hprof 14876
显示当前时间节点堆内存信息:
jmap -heap 14876 >d:\a.txt // 17924 是进程号,输出到d盘的a.txt文件
直接控制台查看堆空间信息:
C:\Windows\system32>jmap -heap 14876
Attaching to process ID 14876, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.291-b10
using thread-local object allocation.
Parallel GC with 8 thread(s)
Heap Configuration: //堆空间的配置信息
MinHeapFreeRatio = 0
MaxHeapFreeRatio = 100
MaxHeapSize = 8550088704 (8154.0MB)
NewSize = 178257920 (170.0MB)
MaxNewSize = 2850029568 (2718.0MB)
OldSize = 356515840 (340.0MB)
NewRatio = 2
SurvivorRatio = 8
MetaspaceSize = 21807104 (20.796875MB)
CompressedClassSpaceSize = 1073741824 (1024.0MB)
MaxMetaspaceSize = 17592186044415 MB
G1HeapRegionSize = 0 (0.0MB)
Heap Usage: //堆空间各区使用状况
PS Young Generation
Eden Space://Eden区
capacity = 134217728 (128.0MB)
used = 123984136 (118.24048614501953MB)
free = 10233592 (9.759513854980469MB)
92.37537980079651% used
From Space: //Survivor from区,或者:S0
capacity = 22020096 (21.0MB)
used = 0 (0.0MB)
free = 22020096 (21.0MB)
0.0% used
To Space: //Survivor to区,或者:S1
capacity = 22020096 (21.0MB)
used = 0 (0.0MB)
free = 22020096 (21.0MB)
0.0% used
PS Old Generation //old区,或者:老年代
capacity = 356515840 (340.0MB)
used = 0 (0.0MB)
free = 356515840 (340.0MB)
0.0% used
3196 interned Strings occupying 261920 bytes.
使用的:ParallelGC垃圾收集器
直接查看进程堆空间历史对象信息
jmap -histo 15440