关于编写Java程序让Jvm崩溃
今天在书上看到一个作者提出一个问题“怎样通过编写Java代码让Jvm崩溃”,我看了之后也不懂。带着问题查了一下,百度知道里面有这样一个答案:
package jvm; public class Crash {
public static void main(String[] args) { //Object[] o = {“abc”};初始值赋值,不会有影响。
Object[] o = null; while (true) {
o = new Object[] { o };
//输出的话,jvm就不会崩溃。
//System.out.println(o);
}
}
}
程序运行十几秒之后,控制台会出现这样的错误:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at jvm.Crash.main(Crash.java:10)
很明显,超出内存空间错误。
我将原程序随意改了一下,如赋初始值等,对程序无影响。
可是我将死循环中的o输出在控制台的时候,jvm居然一直都不崩,为什么输出的话,就不会超出内存空间呢?
我看来,原程序能够使Jvm崩溃,是因为死循环中,通过旧对象,不断创建出新的对象,即创造的对象是互相引用的,所以GC是不会回收它们的,造成堆栈溢出。
仿照这个例子,我写了一个简单的类,模仿例子程序中的数组,如下:
package jvm; public class JvmBean { JvmBean bean = new JvmBean(this); public JvmBean(JvmBean bean){
this.bean = bean;
}
}
然后简单测试,如下:
package jvm; public class MyCrash { public static void main(String[] args) {
JvmBean j = null;
while(true){
j = new JvmBean(j);
//无论输出不输出,jvm都会崩溃
//System.out.println(j);
}
}
}
结果便是控制台输出如下的错误:
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崩溃,可是错误类型跟例子程序的不同,说堆栈溢出错误,并且无论是否输出,错误都一样发生,为什么呢?
由于评论的两位老兄的热心指点,两个问题都水落石出了!
这里过一下整个流程。
第一个异常 结合天添老兄说的,Exception in thread "main" java.lang.OutOfMemoryError: Java heap space at jvm.Crash.main(Crash.java:10)是因为程序无法申请到足够的内存的时候抛出的异常,Object数组o不断指向新的Object数组,数组元素是原来的Object数组,这使得Object维数越来越高。不断申请内存空间,最终导致超出jvm中堆的最大值。堆内存溢出。为什么输出打印,时间会延长呢?yahokuma老兄一言惊醒梦中人!输出打印的话,虚拟机并不是不会崩溃,而是崩溃的时间大大延长了。而崩溃时间延长其实是假象,是因为输出属于IO事件,每次输出CPU都被中断,IO很耗时,所以,感觉上才会时间延长。
第二个异常,yahokuma 老兄在下面评论中已经说的很清楚了,我这里搬过来——“类内部的静态属性 > 静态块 > 对象属性 > 构造方法。注意这一点,那就是说 bean属性会先于JvmBean的构造函数被初始化。在你main函数中,new一个 JvmBean的构造函数之前,类内部的JvmBean对象要优先被初始化,这个类内部的属性bean的内部同样也包含了一个JvmBean对象需要被初始化,成循环调用,造 成了栈溢出。”所以异常才会是这个——Exception in thread "main" java.lang.StackOverflowError
我把原JvmBean改一下
package jvm; public class JvmBean { JvmBean bean = null; public JvmBean(JvmBean bean){
this.bean = bean;
}
}
这样最终得到的结果跟第一个例子一样了。
如何使Jvm崩溃呢?如果想使它堆内存空间不足,造成典型的内存泄漏,可以创建对象,使它们不断向深层次引用。产生Exception in thread "main" java.lang.OutOfMemoryError: Java heap space 这样的错误。如果想使他们栈空间不足,最简单的,就是在方法里,如构造方法里不断申请新的内存空间就够了,如我第二个错误例子的示范。
关于编写Java程序让Jvm崩溃的更多相关文章
- 通过编写Java代码让Jvm崩溃
在书上看到一个作者提出一个问题"怎样通过编写Java代码让Jvm崩溃",我看了之后也不懂.带着问题查了一下,百度知道里面有这样一个答案: 1 package jvm; 2 3 pu ...
- 写Java程序让Jvm崩溃
package jvm; public class HeapCrash { public static void main(String[] args) { //Object[] o = {“abc” ...
- 35.按要求编写Java程序: (1)编写一个接口:InterfaceA,只含有一个方法int method(int n); (2)编写一个类:ClassA来实现接口InterfaceA,实现int method(int n)接口方 法时,要求计算1到n的和; (3)编写另一个类:ClassB来实现接口InterfaceA,实现int method(int n)接口 方法时,要求计算n的阶乘(n
35.按要求编写Java程序: (1)编写一个接口:InterfaceA,只含有一个方法int method(int n): (2)编写一个类:ClassA来实现接口InterfaceA,实现in ...
- 初学编写JAVA程序
一.编写JAVA程序 编写JAVA程序,输出一行文本信息:“Hello world”,选择编辑器eclipse,打开之后编写程序 public class Hello{ public static v ...
- Java初学者作业——使用记事本编写Java程序
返回本章节 返回作业目录 需求说明: 使用记事本编写 Java 程序,输出"大家好!我的梦想是做一名 Java 高级工程师!". 为 Java 程序添加单行和多行注释以及文档注释. ...
- Java初学者作业——编写Java程序,实现用户登录验证。
返回本章节 返回作业目录 需求说明: 编写Java程序,实现用户登录验证. 若用户名与密码输入正确,则提示"登录成功,欢迎回来!",若用户名与密码不匹配,则提示"用户名和 ...
- Java初学者作业——编写Java程序,根据输入的某个班级的学员成绩,计算该班级学员的平均成绩,要求输入班级的人数。
返回本章节 返回作业目录 需求说明: 编写Java程序,根据输入的某个班级的学员成绩,计算该班级学员的平均成绩,要求输入班级的人数. 实现思路: 声明变量sum.count以及avg用于存储总成绩.班 ...
- Java初学者作业——编写Java程序,输入一个数字,实现该数字阶乘的计算。
返回本章节 返回作业目录 需求说明: 编写Java程序,输入一个数字,实现该数字阶乘的计算.一个数字的阶乘是所有小于及等于该数的正整数的积,自然数n的阶乘写作n! .例如,5的阶乘等于1*2*3*4* ...
- Java初学者作业——编写Java程序,实现判断所输入字符的类型(数字、小写字母、大写字母或其他字符)
返回本章节 返回作业目录 需求说明: 编写Java程序,实现判断所输入字符的类型(数字.小写字母.大写字母或其他字符) 实现思路: 声明变量c,用于存储用户输入的字符. 通过Scanner接收用户输入 ...
随机推荐
- C#语句2——循环语句(for穷举、迭代和while循环)
一.for循环拥有两类: (一).穷举: 把所有可能的情况都走一遍,使用if条件筛选出来满足条件的情况. 1.单位给发了一张150元购物卡,拿着到超市买三类洗化用品.洗发水15元,香皂2元,牙刷5元. ...
- T-SQL基础--TOP
理解TOP子句 众所周知,TOP子句可以通过控制返回行的数量来影响查询. 我们知道TOP子句能很容易的满足返回指定行数的子集,接下来有一些例子来展示什么情况下使用TOP子句来返回一个结果集: 你打算返 ...
- Spring CharacterEncodingFilter
<!-- 配置请求过滤器,编码格式设为UTF-8,避免中文乱码--> <filter> <filter-name>springUtf8Encoding</fi ...
- coursera机器学习笔记-多元线性回归,normal equation
#对coursera上Andrew Ng老师开的机器学习课程的笔记和心得: #注:此笔记是我自己认为本节课里比较重要.难理解或容易忘记的内容并做了些补充,并非是课堂详细笔记和要点: #标记为<补 ...
- mysql错误一例:ERROR 1030 (HY000): Got error 28 from storage engine
在使用mysqldump导出一份建库脚本是,发生了下面的错误: 当执行 desc table_name; 时也报错: tag为表名,show index from tag;倒是可以执行. 其实真正的错 ...
- svn使用--all-static编译,移植到其它系统上可能使setlocale等GLIBC相关库函数调用失败
svn: Can't convert string from 'UTF-8' to native encoding
- css3 border-radius
前缀对应浏览器 前缀 浏览器 -webkit chrome和safari -moz firefox -ms IE -o opera border-radius: <style type=&quo ...
- [转]C# 连接 Oracle 的几种方式
本文转自:http://www.cnblogs.com/storys/archive/2013/03/06/2945914.html 一:通过System.Data.OracleClient(需要安装 ...
- [转]html5 js 访问 sqlite 数据库的操作类
本文转自:http://blog.csdn.net/tsxw24/article/details/7613815 webkit 核心的浏览器提供了 3个 api接口,用于访问本地sqlite数据,但使 ...
- 【2016-10-13】【坚持学习】【Day4】【模板方法模式】
今天学习模板方法模式 例子代码; 模板抽象类,定义了一套流程,有一些方法已经实现,有一些抽象方法需要继承它的子类实现 abstract class DataViewer { //抽象方法:获取数据 p ...