一、堆溢出
堆溢出很好实现,一直创建对象。
/**
* 堆溢出
*VM Args:-Xms10m -Xmx10m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=C:\Users\chenlige\Desktop\jvm
*/
public class Heap{
public static void main(String[] args){
ArrayList list=new ArrayList();
while(true){
list.add(new Heap());
}
}
}
还有一种,不停的在运行时常量池中添加。jdk1.7后常量池已经放到heap中,所以会报堆溢出,如果是1.6之前会报方法区溢出
public static void main(String[] args) {
// 使用List保持着常量池引用,避免Full GC回收常量池行为
List<String> list = new ArrayList<String>();
int i = 0;
while (true) {
list.add(String.valueOf(i++).intern());
}
}
java.lang.OutOfMemoryError: Java heap space
二、栈溢出
/**
* VM Args:-Xss 128k
* 栈溢出
*/
public class Stack{
public static void main(String[] args){
new Stack().test();
}
public void test(){
test();
}
}
Exception in thread "main" java.lang.StackOverflowError
三、方法区溢出
当运行时常量池过大或者类过多时就会导致方法区溢出
方法区用于存放Class的相关信息,如:类名,访问修饰符,常量池,字符描述,方法描述等。对于这个区域的测试,基本思路是运行时产生大量的类去填满方法区,直到溢出。
while (true) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(OOMObject.class);
enhancer.setUseCache(false);
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable {
return null;
}
});
enhancer.create();
}