实验一:程序计数器不会导致异常
package error;
/**
* 实验:Java内存模型中程序计数器是唯一一个不会发生OutOfMemoryError的内存区域
* 思路:开启任意多个线程,每个线程一个程序计数器,验证是否会产生异常
* 结果:程序不会终止,一直创建线程,但是会同时运行8个线程(4处理器2核),并且线程轮流切换,but死机了。。。
*/
class OutOfMemoryTest1 {
class EndLessThread extends Thread {
private int number;
EndLessThread(int number) {
this.number = number;
}
public void run() {
System.out.println("thread number is:" + number);
}
}
private void endLessMethod() {
while (true) {}
}
public void createThreads() {
int i = 0;
while (++i > 0) {
new EndLessThread(i).start();
}
}
public static void main(String[] args) {
new OutOfMemoryTest1().createThreads();
}
}
实验1截图
实验二:虚拟机申请栈深度大于虚拟机所允许的大小
package error;
/**
* 实验:Java虚拟机栈当请求内存但是不够分配时会产生异常
* 思路:每一个方法调用会有栈帧入栈,递归调用,那么方法所需的栈帧无限大,查看是否会发生异常
* 结果:递归调用了6000多次后,发生了StackOverflowError
*/
public class OutOfMemoryTest2 {
public void invokeSelf(int number) {
System.out.println("number = [" + number + "]");
invokeSelf(++number);
}
public static void main(String[] args) {
new OutOfMemoryTest2().invokeSelf(1);
}
}
实验2结果:
实验3:堆中没有内存完成实例分配,并且也不能扩展时
package error;
import java.util.ArrayList;
import java.util.List;
/**
* 实验:堆中没有内存完成实例分配,并且也不能扩展时
* 思路:限制堆的最大大小,不断创建对象
* 结果:发生异常
*/
public class OutOfMemoryTest3 {
private String number = new String("123123123123");
public void bigStackFrame() {
List<OutOfMemoryTest3> list = new ArrayList<OutOfMemoryTest3>();
long i = 0;
while (++i > 0) {
list.add(new OutOfMemoryTest3());
}
}
public static void main(String[] args) {
new OutOfMemoryTest3().bigStackFrame();
}
}
运行时添加jvm参数,-Xms8M -Xmx16M,限制虚拟机最大内存。
实验3结果: