文章为 深入理解java虚拟机 第三版 周志明 著 读书笔记 仅供学习交流
1 java堆溢出
/** * @Author: QinMY * @Date: 2021/3/26 17:27 * @Des: VM args;-Xms20m -Xmx20m -XX:+HeapDumpOutOfMemoryError */ public class HeapOOM { static class OOMObject{} public static void main(String[] args) { List<OOMObject> list = new ArrayList<>(); while (true){ list.add(new OOMObject()); } } }
结果: Dumping heap to java_pid5980.hprof ... Heap dump file created [28342993 bytes in 0.065 secs]
2 虚拟机栈和本地方法栈溢出
HotSport虚拟机不区分虚拟机栈和本地方法栈,都通过-Xss来设置栈大小
如果线程请求深度大于栈深度则抛出 StackOverFlowError异常
-
使用-Xss减少栈内存容量
/** * @Author: QinMY * @Date: 2021/3/26 17:53 * @Des: VM ars: -Xss128k */ public class JavaVMStackSOF { private int stackLength = 1; public void stackLeak(){ stackLength++; stackLeak(); } public static void main(String[] args) { JavaVMStackSOF javaVMStackSOF = new JavaVMStackSOF(); try { javaVMStackSOF.stackLeak(); }catch (Throwable e){ System.out.println("stack length: "+javaVMStackSOF.stackLength); throw e; } } }
结果: stack length: 999 Exception in thread "main" java.lang.StackOverflowError at jvm.JavaVMStackSOF.stackLeak(JavaVMStackSOF.java:12) at jvm.JavaVMStackSOF.stackLeak(JavaVMStackSOF.java:13) at jvm.JavaVMStackSOF.stackLeak(JavaVMStackSOF.java:13) at jvm.JavaVMStackSOF.stackLeak(JavaVMStackSOF.java:13)
如果虚拟机栈允许动态扩展,档扩展到无法申请到足够内存时抛出 StackOverFlowError异常
HotSport虚拟机不允许动态扩展
3 方法区和运行时常量池溢出
方法区的主要职责是用于存放类型的相关信息,如类 名、访问修饰符、常量池、字段描述、方法描述等。对于这部分区域的测试,基本的思路是运行时产
生大量的类去填满方法区,直到溢出为止。
在JDK 8以后,永久代便完全退出了历史舞台,元空间作为其替代者登场。在默认设置下正常的动态创建新类型的测试用例已经很难再迫使虚拟机产生方法区的溢出异常了。
4 本机内存直接溢出
直接内存(Direct Memory)的容量大小可通过-XX:MaxDirectMemorySize参数来指定,如果不 去指定,则默认与Java堆最大值(由-Xmx指定)一致。
/** * @Author: QinMY * @Date: 2021/3/27 11:01 * @Des: vm args -Xmx20m -xx:MaxDirectMemorySize=10m */ public class DirectMemoryOOM { private static final int _1m = 1024 * 1024; public static void main(String[] args) throws IllegalAccessException { Field declaredField = Unsafe.class.getDeclaredFields()[0]; declaredField.setAccessible(true); Unsafe unsafe = (Unsafe) declaredField.get(null); while (true) { unsafe.allocateMemory(_1m); } } }
结果: Exception in thread "main" java.lang.OutOfMemoryError at sun.misc.Unsafe.allocateMemory(Native Method) at jvm.DirectMemoryOOM.main(DirectMemoryOOM.java:23)