1.JVM–堆内存OOM_实例溢出
练习内容:java.lang.OutOfMemoryError: Java heap space
代码:代码出自《深入理解java虚拟机》
/*
* VM Args:-Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError
*/
public class HeapOOM {
static class OOMObject{
}
public static void main(String[] args) {
List<OOMObject> oomlist=new ArrayList<>();
while(true) {
if( oomlist.size() %1000 == 0) {
System.out.println(oomlist.size());
}
oomlist.add(new OOMObject());
}
}
}
内存设置:eclipse:run as—>run configurations–>Arguments
用注释的即可。
日志情况:
1822000
1823000
java.lang.OutOfMemoryError: Java heap space
Dumping heap to java_pid3644.hprof …
Heap dump file created [61455147 bytes in 0.180 secs]
Exception in thread “main” java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Arrays.java:3210)
at java.util.Arrays.copyOf(Arrays.java:3181)
at java.util.ArrayList.grow(ArrayList.java:261)
at java.util.ArrayList.ensureExplicitCapacity(ArrayList.java:235)
at java.util.ArrayList.ensureCapacityInternal(ArrayList.java:227)
at java.util.ArrayList.add(ArrayList.java:458)
at jvm.HeapOOM.main(HeapOOM.java:18)
异常后,由于设置 -XX:+HeapDumpOnOutOfMemoryError,会产生dump文件
dump文件:默认在项目主目录下
F:\EB-Worker\test\My\java_pid9660.hprof
dump分析:可以使用 VisualVM.exe,jdk自带工具,选择dump文件即可分析
基础信息
实例情况:
根据代码,new 了很多 oomobject 。此外用arraylist存储,是object[]
2.常量池溢出
代码:代码出自《深入理解jvm虚拟机》
书中代码针对的是jdk 1.6版。当时 常量存放于永久代。故而可以试验出来。
但是现在实验是 1.8版,取消了永久代的概念。我们不加参数,开始跑。结果如下:
/*
* VM Args:-XX:PermSize=10M -XX:MaxPermSize=10M
*/
public class RuntimeConstantPoolOOM {
public static void main(String[] args) {
//保持引用
List<String> list = new ArrayList<>();
int i=0;
while(true) {
//intern方法:native,如果常量池存在则返回,否则新增
list.add(String.valueOf(i++).intern());
if(i%1000==0) {
System.out.println(i);
}
}
}
}
说明常量 存放于 堆中。因此
-Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError
异常如下:
316000
317000
java.lang.OutOfMemoryError: GC overhead limit exceeded
Dumping heap to java_pid13464.hprof ...
Heap dump file created [25236182 bytes in 0.143 secs]
Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded
补充:
1.8版,取消了永久代的概念,增加了mataspace,不再是存储在连续的堆空间上,而是移动到叫做“Metaspace”的本地内存(Native memory)中。
通过 -XX:MetaspaceSize=40M ,-XX:MaxMetaspaceSize来控制大小(如果初始化时类加载很多,可以初始化下。否则会出现多次GC,然后该区域内存扩充)