堆相关信息的查看
package JVMHere;
public class TestFirst {
public static void main(String[] args) {
//返回虚拟机试图使用的最大内存
long max = Runtime.getRuntime().maxMemory(); //字节 1024 * 1024
//返回JVM的总内存
long total = Runtime.getRuntime().totalMemory();
System.out.println("max:" + max + "字节"+(max/(double)1024/1024)+"MB");
System.out.println("total:" + total + "字节"+(total/(double)1024/1024)+"MB");
/*
默认情况下: 分配的总内存是电脑内存的1/4,而初始化是1/64
出现OOM,首先是尝试将堆内存扩大,在vm options里面添加:
-Xms1024m -Xmx1024m -XX:+PrintGCDetails
还报错就是代码问题。
分析内存(专业工具)
*/
/*
结果:
max:1029177344字节981.5MB
total:1029177344字节981.5MB
Heap
PSYoungGen total 305664K, used 15729K [0x00000000eab00000, 0x0000000100000000, 0x0000000100000000)
eden space 262144K, 6% used [0x00000000eab00000,0x00000000eba5c420,0x00000000fab00000)
from space 43520K, 0% used [0x00000000fd580000,0x00000000fd580000,0x0000000100000000)
to space 43520K, 0% used [0x00000000fab00000,0x00000000fab00000,0x00000000fd580000)
ParOldGen total 699392K, used 0K [0x00000000c0000000, 0x00000000eab00000, 0x00000000eab00000)
object space 699392K, 0% used [0x00000000c0000000,0x00000000c0000000,0x00000000eab00000)
Metaspace used 3470K, capacity 4496K, committed 4864K, reserved 1056768K
class space used 377K, capacity 388K, committed 512K, reserved 1048576K
Process finished with exit code 0
305664+699392=1,005,056
1,005,056/1024 = 981.5
也就解释了元空间,逻辑上存在,物理上不存在
*/
}
}
OOM错误初步认识
package JVMHere;
import java.util.Random;
import java.util.UUID;
//OOM报错测试
public class OOMTest {
public static void main(String[] args) {
String str = "aaaaaaaaaaaaaaaaaaaaaa";
while (true) {
str += str + new Random().nextInt(88888888) + UUID.randomUUID().toString();
}
/*
"C:\Program Files\Java\jdk1.8.0_162\bin\java.exe" -Xms10m -Xmx10m -XX:+PrintGCDetails "-javaagent:F:\Program Files\JetBrains\IntelliJ IDEA 2019.3.2\lib\idea_rt.jar=51802:F:\Program Files\JetBrains\IntelliJ IDEA 2019.3.2\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_162\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_162\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_162\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_162\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_162\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_162\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_162\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_162\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_162\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_162\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_162\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_162\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_162\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_162\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_162\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_162\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_162\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_162\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_162\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_162\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_162\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_162\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_162\jre\lib\rt.jar;F:\SpringStudy\SpringBootStudySecond\mianshi\out\production\mianshi" JVMHere.OOMTest
[GC (Allocation Failure) [PSYoungGen: 2048K->488K(2560K)] 2048K->768K(9728K), 0.0037399 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[GC (Allocation Failure) [PSYoungGen: 2468K->506K(2560K)] 2748K->1326K(9728K), 0.0017603 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[GC (Allocation Failure) [PSYoungGen: 2516K->488K(2560K)] 3337K->1572K(9728K), 0.0007417 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[GC (Allocation Failure) [PSYoungGen: 2370K->488K(2560K)] 3454K->2627K(9728K), 0.0016351 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Ergonomics) [PSYoungGen: 1580K->0K(2560K)] [ParOldGen: 6363K->2254K(7168K)] 7943K->2254K(9728K), [Metaspace: 4415K->4415K(1056768K)], 0.0079246 secs] [Times: user=0.05 sys=0.00, real=0.01 secs]
[GC (Allocation Failure) [PSYoungGen: 1135K->0K(2560K)] 5502K->4366K(9728K), 0.0008514 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[GC (Allocation Failure) [PSYoungGen: 0K->0K(1536K)] 4366K->4366K(8704K), 0.0008611 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Allocation Failure) [PSYoungGen: 0K->0K(1536K)] [ParOldGen: 4366K->4339K(7168K)] 4366K->4339K(8704K), [Metaspace: 4415K->4415K(1056768K)], 0.0130044 secs] [Times: user=0.02 sys=0.00, real=0.01 secs]
[GC (Allocation Failure) [PSYoungGen: 0K->0K(2048K)] 4339K->4339K(9216K), 0.0005347 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Allocation Failure) [PSYoungGen: 0K->0K(2048K)] [ParOldGen: 4339K->4285K(7168K)] 4339K->4285K(9216K), [Metaspace: 4415K->4415K(1056768K)], 0.0183815 secs] [Times: user=0.03 sys=0.00, real=0.02 secs]
Heap
PSYoungGen total 2048K, used 49K [0x00000000ffd00000, 0x0000000100000000, 0x0000000100000000)
eden space 1024K, 4% used [0x00000000ffd00000,0x00000000ffd0c750,0x00000000ffe00000)
from space 1024K, 0% used [0x00000000ffe00000,0x00000000ffe00000,0x00000000fff00000)
to space 1024K, 0% used [0x00000000fff00000,0x00000000fff00000,0x0000000100000000)
ParOldGen total 7168K, used 4285K [0x00000000ff600000, 0x00000000ffd00000, 0x00000000ffd00000)
object space 7168K, 59% used [0x00000000ff600000,0x00000000ffa2f4b0,0x00000000ffd00000)
Metaspace used 4447K, capacity 4632K, committed 4992K, reserved 1056768K
class space used 497K, capacity 524K, committed 640K, reserved 1048576K
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:674)
at java.lang.StringBuilder.append(StringBuilder.java:208)
at JVMHere.OOMTest.main(OOMTest.java:11)
Process finished with exit code 1
*/
}
}
定位错误
如果一个项目出现OOM错误,该如何排错?
- 能够看到第几行出错,JProfiler工具查看
- Dubug,一行行分析(难)
MAT,JProfiler的作用
- 分析Dump内存文件,快速定位内存泄漏
- 获取堆中数据
- 获得最大对象
- …
使用JProfile分析,,,,,vm options
-Xms1m -Xmx8m -XX:+HeapDumpOnOutOfMemoryError
去文件夹找到生成的文件,用JProfile打开就可以分析了。
package JVMHere;
import java.util.ArrayList;
//-Xms1m -Xmx8m -XX:+HeapDumpOnOutOfMemoryError
public class OOMTest2 {
byte[] array = new byte[1*1024*1024]; //1M
public static void main(String[] args) {
ArrayList<OOMTest2> list =new ArrayList<>();
int count = 0;
try{
while(true){
list.add(new OOMTest2());
count++;
}
}catch (Exception e){
//Throwable
//Exception
//error
//所以用Exception捕获不到
System.out.println("count : "+count);
e.printStackTrace();
}
}
}
补充:堆的图解