1. 堆溢出
Java堆内存存储对象实例,故溢出只需要疯狂的创建对象即可,但因为回收,需要链表引用防止回收
public class HeapOOM { public static void main(String[] args) { // 因为会被回收,所以搞个list引用他们,则存在 List<Object> list = new ArrayList<Object>(); int i = 0; while (true) { list.add(new Integer(i++)); } } } |
2. 虚拟机栈和本地方法栈溢出
栈中存储的线程对应的方法入栈,故不断的递归即可
public class JavaVMStackSOF { private int stackLength = 1; public void stackLeak() { stackLength++; stackLeak(); }
public static void main(String[] args) throws Throwable { JavaVMStackSOF oom = new JavaVMStackSOF(); try { oom.stackLeak(); } catch (Throwable e) { System.out.println("stack length:" + oom.stackLength); throw e; } } } |
3. 方法区和动态常量池溢出
因为方法区存的是动态常量、class对象等,故需要溢出的话就是疯狂的插入动态常量或创建class对象即可
a) 插入动态常量
public class RuntimeConstantPoolOOM { public static void main(String[] args) { // 使用List保持着常量池引用,避免Full GC回收常量池行为 List<String> list = new ArrayList<String>(); // 10MB的PermSize在integer范围内足够产生OOM了 int i = 0; while (true) { list.add(String.valueOf(i++).intern()); } } } |
b) 使用cglib创建class
4. 本机直接内存溢出
直接内存就是读取文件的时候,故直接读取一个大文件即可