今天在书上看到一个作者提出一个问题“怎样通过编写Java代码让Jvm崩溃”,我看了之后也不懂。带着问题查了一下,百度知道里面有这样一个答案:

 1 package jvm;
 2 
 3 public class Crash {
 4     public static void main(String[] args) {
 5         
 6         //Object[] o = {“abc”};初始值赋值,不会有影响。
 7         Object[] o = null;
 8 
 9         while (true) {
10             o = new Object[] { o };
11             //输出的话,jvm就不会崩溃。
12             //System.out.println(o);
13         }        
14     }
15 }

程序运行十几秒之后,控制台会出现这样的错误:

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
    at jvm.Crash.main(Crash.java:10)

很明显,超出内存空间错误。

我将原程序随意改了一下,如赋初始值等,对程序无影响。

可是我将死循环中的o输出在控制台的时候,jvm居然一直都不崩,为什么输出的话,就不会超出内存空间呢?

 

我看来,原程序能够使Jvm崩溃,是因为死循环中,通过旧对象,不断创建出新的对象,即创造的对象是互相引用的,所以GC是不会回收它们的,造成堆栈溢出。

仿照这个例子,我写了一个简单的类,模仿例子程序中的数组,如下:

 1 package jvm;
 2 
 3 public class JvmBean {
 4 
 5     JvmBean bean = new JvmBean(this);
 6     
 7     public JvmBean(JvmBean bean){
 8         this.bean = bean;
 9     }
10 }

然后简单测试,如下:

 1 package jvm;
 2 
 3 public class MyCrash {
 4 
 5     public static void main(String[] args) {
 6         JvmBean j = null;
 7         while(true){
 8             j = new JvmBean(j);
 9             //无论输出不输出,jvm都会崩溃
10             //System.out.println(j);
11         }
12     }
13 }

结果便是控制台输出如下的错误:

Exception in thread "main" java.lang.StackOverflowError
    at jvm.JvmBean.<init>(JvmBean.java:5)
    at jvm.JvmBean.<init>(JvmBean.java:5)
    at jvm.JvmBean.<init>(JvmBean.java:5)
    at jvm.JvmBean.<init>(JvmBean.java:5)
    at jvm.JvmBean.<init>(JvmBean.java:5)

一长串的"at jvm.JvmBean.<init>(JvmBean.java:5)",后面的被我省略了。

结果看来,同样也造成了jvm崩溃,可是错误类型跟例子程序的不同,说堆栈溢出错误,并且无论是否输出,错误都一样发生,为什么呢?

 

 

由于评论的两位老兄的热心指点,两个问题都水落石出了!

这里过一下整个流程。

第一个异常 结合yahokuma老兄一言惊醒梦中人!输出打印的话,虚拟机并不是不会崩溃,而是崩溃的时间大大延长了。而崩溃时间延长其实是假象,是因为输出属于IO事件,每次输出CPU都被中断,IO很耗时,所以,感觉上才会时间延长。

第二个异常,

我把原JvmBean改一下

 1 package jvm;
 2 
 3 public class JvmBean {
 4 
 5     JvmBean bean = null;
 6     
 7     public JvmBean(JvmBean bean){
 8         this.bean = bean;
 9     }
10 }

这样最终得到的结果跟第一个例子一样了。

 

如何使Jvm崩溃呢?如果想使它堆内存空间不足,造成典型的内存泄漏,可以创建对象,使它们不断向深层次引用。产生Exception in thread "main" java.lang.OutOfMemoryError: Java heap space 这样的错误。如果想使他们栈空间不足,最简单的,就是在方法里,如构造方法里不断申请新的内存空间就够了,如我第二个错误例子的示范。

相关文章:

  • 2022-12-23
  • 2021-07-06
  • 2021-11-22
  • 2022-12-23
  • 2021-10-03
  • 2021-11-24
  • 2021-06-16
猜你喜欢
  • 2021-06-13
  • 2022-12-23
  • 2021-11-02
  • 2022-01-03
  • 2021-05-19
  • 2022-12-23
  • 2021-06-23
相关资源
相似解决方案