Java堆异常测试
/**
* Java堆异常测试
* Vm Args: -Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError
*/
public class jvm2_3 {
static class OOMObject{}
public static void main(String[] args) {
List<OOMObject> list = new ArrayList<OOMObject>();
while (true){
list.add(new OOMObject());
}
}
}
虚拟机栈和本地方法栈OOM测试
/**
* 虚拟机栈和本地方法栈OOM测试
* 实例结果:error(Exception in thread "main" java.lang.StackOverflowError),
* 在单个线程下,无论是由于栈帧太大还是虚拟机容量太小,当内存无法分配的时候,虚拟机抛出
* 的都是StackOverflowError异常
* VM Args: -Xss160k
*/
public class jvm2_4 {
private int stackLength = 1;
public void stackLeak(){
stackLength++;
stackLeak();
}
public static void main(String[] args) {
jvm2_4 jvm24 = new jvm2_4();
try {
jvm24.stackLeak();
}catch (Throwable e){
System.out.println("stack length:" + jvm24.stackLength);
throw e;
}
}
}
创建线程导致内存溢出异常
/**
* 创建线程导致内存溢出异常
* 实例结果:基本上运行就会死机,这里通过不断的建立线程的方式可以产生内存异常。
* 解决方法:如果是建立过多线程导致内存溢出,再不能减少线程数或者更换64虚拟机
* 的情况下,就只能通过减少最大堆和减少栈容量来换取更多的线程。
* VM Args: -Xss2M
*/
public class jvm2_5 {
private static void dontStop(){
while (true){}
}
public static void main(String[] args) {
//这里不停的循环创建线程
while (true){
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
dontStop();
}
});
thread.start();
}
}
}
运行时常量池导致的内存溢出异常
/**
* 运行时常量池导致的内存溢出异常
* VM Args: -XX:PermSize=10M -XX:MaxPermSize=10M
* 实例结果:从运行中可以看到,运行时常量池溢出,在OutOfMemoryError后面跟随的
* 提示信息是"PermGen space",说明运行时常量池属于方法区(HotSpot虚拟机中的永久代)的一部分。
* 说明:jdk1.6和jdk1.7以及以后的运行结果不同,在jdk1.6及以前的版本中,由于常量池分配在永久代内,
* 我们可以通过-XX:PermSize和-XX:MaxPermSize限制方法大小,从而间接限制其中常量池的容量。而使用
* jdk1.7运行将不会出现如上结果,while循环将一直进行下去。
* 补充:jdk1.8以及以后对-XX:PermSize=10M -XX:MaxPermSize=10M参数移除。
*/
public class jvm2_6 {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
int i = 0;
while (true){
list.add(String.valueOf(i++).intern());
}
}
}