在园子中看见了这个园友的问题,高手指点一下,关于编写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);
}
}
}

  如果我直接运行这个程序,等了好久也没有出现下面的异常,因为什么和那个兄台的结果不一样,答案很简单就是我们的环境不一样,jvm的运行参数也不一样:  

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

  下面看一下在我执行这段代码什么都不加的情况下的jps的监控信息:  

C:\Users\Think>jps -v
7888 org.eclipse.equinox.launcher_1.3.0.v20130327-1440.jar -Dosgi.requiredJavaVe
rsion=1.6 -Xms40m -Xmx512m -XX:MaxPermSize=256m
7772 Jps -Dapplication.home=E:\Program Files\Java\jdk1.7.0_40 -Xms8m
7108 Crash -Dfile.encoding=UTF-8

  其中这条记录7108 Crash -Dfile.encoding=UTF-8就是我们执行的程序,在下面也看到了有4个垃圾回收的线程在进行内存回收,并没有指定heap和stack的大小,使用的都是默认值,我觉得我可以用这个程序出抛出stack和heap的异常,下面我把虚拟机运行的堆的参数改小了,改成5M吧:具体方法查看我的这篇从内存溢出看Java 环境中的内存结构

  

  执行,出现了如下问题,  

Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded
at jvm.Crash.main(Crash.java:10)

  可以在sun的网站上找到这个Bug的原因以及解决办法:http://www.oracle.com/technetwork/java/javase/gc-tuning-6-140523.html,大概意思就是我花了太多的时间(98%),但是回收的垃圾太少了(2%)。

he concurrent collector will throw an OutOfMemoryError if too much time is being spent in garbage collection: if more than 98% of the total time is spent in garbage collection and less than 2% of the heap is recovered, an OutOfMemoryError will be thrown. This feature is designed to prevent applications from running for an extended period of time while making little or no progress because the heap is too small. If necessary, this feature can be disabled by adding the option -XX:-UseGCOverheadLimit to the command line.

  加上-XX:-UseGCOverheadLimit参数以后通过jps命令查看参数:

  

  出现:  

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

  加上输出语句以后代码如下:  

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);
}
}
}

  再次执行程序,参数没有变化,结果依然出现异常:  

[Ljava.lang.Object;@72e0726b
[Ljava.lang.Object;@63c6472d
[Ljava.lang.Object;@5c71c17e
[Ljava.lang.Object;@786aa48e
[Ljava.lang.Object;@437f3fe
[Ljava.lang.Object;@725d61a4
[Ljava.lang.Object;@402b2861
[Ljava.lang.Object;@94dc811
[Ljava.lang.Object;@7e6d0650
[Ljava.lang.Object;@4d5f4924
[Ljava.lang.Object;@20c88c8a
[Ljava.lang.Object;@57d74d5f
[Ljava.lang.Object;@3f8d2560
[Ljava.lang.Object;@1b663c05
[Ljava.lang.Object;@2046942e
[Ljava.lang.Object;@184bcffd
[Ljava.lang.Object;@1b97d23c
[Ljava.lang.Object;@6207775d
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOfRange(Unknown Source)
at java.lang.String.<init>(Unknown Source)
at java.lang.Integer.toUnsignedString(Unknown Source)
at java.lang.Integer.toHexString(Unknown Source)
at java.lang.Object.toString(Object.java:237)
at java.lang.String.valueOf(Unknown Source)
at java.io.PrintStream.println(Unknown Source)
at jvm.Crash.main(Crash.java:12)

  输出的时候将上面的日志内容省略了一部分。接下来是第二个例子,要知道在堆中保存的是对象的实例,在例子中:  

JvmBean j = null;
while (true) {
j = new JvmBean(j);
// 无论输出不输出,jvm都会崩溃
// System.out.println(j);
}

   很显然和第一个Object的例子不一样,看着JbmBean的定义:  

package jvm;

public class JvmBean {

    JvmBean bean = new JvmBean(this);

    public JvmBean(JvmBean bean){
this.bean = bean;
}
}

  就知道这个程序跟门就没有循环,在第一次进到循环的时候就挂了。// System.out.println(j);这句根本就执行不到。OK,我帮你修改一下:把Jvm类改为如下:  

public class JvmBean {
JvmBean bean = null; public JvmBean(JvmBean bean) {
System.out.println(1);
this.bean = bean;
}
}

  然后改一下JVM的运行参数:

  

  运行结果如下:  

public class JvmBean {
JvmBean bean = null; public JvmBean(JvmBean bean) {
System.out.println(1);
this.bean = bean;
}
}

  所以我猜测你在第二个例子自己写的类中抛出的异常应该不是你想象中的场景。

  

  收拾收拾回家,希望能解答你的疑惑。

  

  

  

  

  

  

  

尝试解答java内存问题的更多相关文章

  1. JMM(java内存模型)

    What is a memory model, anyway? In multiprocessorsystems, processors generally have one or more laye ...

  2. Java 内存管理

    java 内存管理机制 JAVA 内存管理总结 java 是如何管理内存的 Java 的内存管理就是对象的分配和释放问题.(两部分) 分配 :内存的分配是由程序完成的,程序员需要通过关键字 new 为 ...

  3. java 内存模型

    翻译自wiki百科:https://en.wikipedia.org/wiki/Java_memory_model 没找到直接在wiki上编辑中文的页面,我就在这翻译下,自己学习用. java内存模型 ...

  4. 【深入Java虚拟机】之一:Java内存模型与内存溢出

    [深入Java虚拟机]之:Java内存区域与内存溢出 高速缓存模型如下: ----------------------------------------------------分割线-------- ...

  5. java内存管理机制

    JAVA 内存管理总结 1. java是如何管理内存的 Java的内存管理就是对象的分配和释放问题.(两部分) 分配 :内存的分配是由程序完成的,程序员需要通过关键字new 为每个对象申请内存空间 ( ...

  6. 修复 Java 内存模型,第 1 部分——Brian Goetz

    转自Java并发大师Brain Goetz:http://www.ibm.com/developerworks/cn/java/j-jtp02244/ (中文地址) http://www.ibm.co ...

  7. Java内存溢出详解

    转自:http://elf8848.iteye.com/blog/378805 一.常见的Java内存溢出有以下三种: 1. java.lang.OutOfMemoryError: Java heap ...

  8. java内存模型及分块

    转自:http://www.cnblogs.com/BangQ/p/4045954.html 1.JMM简介 2.堆和栈 3.本机内存 4.防止内存泄漏   1.JMM简介   i.内存模型概述 Ja ...

  9. java 内存 垃圾回收调优

    要了解Java垃圾收集机制,先理解JVM内存模式是非常重要的.今天我们将会了解JVM内存的各个部分.如何监控以及垃圾收集调优. Java(JVM)内存模型 正如你从上面的图片看到的,JVM内存被分成多 ...

随机推荐

  1. ssh-debian87.sh

    #!/bin/bash sed -i 's/PermitRootLogin without-password/PermitRootLogin yes/g' /etc/ssh/sshd_config s ...

  2. iOS 实现设备应用之间的相互切换

    今天突发奇想,想做个应用之间能够切换的demo. 前提条件是,你得知道对应应用程序的URL Scheme.URL Scheme不一定和bundle id相同,但是,一定要是一致的. [[UIAppli ...

  3. 关于jdk与jre的区别

    JDK:Java Development Kit JRE顾名思义是java运行时环境,包含了java虚拟机,java基础类库.是使用java语言编写的程序运行所需要的软件环境,是提供给想运行java程 ...

  4. 手机App测试如何获取包名的入口【两种方式】

    在进行手机APP测试的时候经常要获取包名.那么何为包名呢?简单来说其实就是手机APP的安装apk文件的名称,每个手机APP(软件)的包名都是唯一的. 那么我们怎样来获取包名以及包名的入口呢? 方法一: ...

  5. J2EE的十三个技术——Servlet

    简介: 基于协议的请求/响应服务的Java类.通俗的说,Servlet是在服务器上运行的小程序.为什么叫Servlet?Applet表示小应用程序,Server+Applet即为Servlet,表示小 ...

  6. sqlserver 汉字转拼音 首写字母 索引 函数

    create function fun_getPY(@str nvarchar(4000)) returns nvarchar(4000) as begin declare @word nchar(1 ...

  7. Struts1 生成Action请求的几种方式分析

    1 直接硬编码 <a href="/Lesson14_Struts1_Demo1//user/regUserDo.do">注册</a><br/> ...

  8. [bzoj4945][Noi2017]游戏

    题目大意:有$n$个位置,有三种数,每个位置只可以填一种数,$d(d\leqslant8)$个位置有三种选择,其他位置只有两种选择.有一些限制,表示第$i$个位置选了某种数,那么第$j$个位置就只能选 ...

  9. [洛谷P4630][APIO2018] Duathlon 铁人两项

    题目大意:给一张无向图,求三元组$(u,v,w)$满足$u->v->w$为简单路径,求个数 题解:圆方树,缩点后$DP$,因为同一个点双中的点一定地位相同 卡点:1.$father$数组开 ...

  10. BZOJ 2223 [Coci 2009]PATULJCI | 主席树练习 (好像是个权限题啊)

    题目: 给个序列,问[l,r]区间内是否存在x>(r-l+1)>>1 题解: 好像大家都觉得这个题比较简单,没人写题解啊 先说BZOJ样例的格式应该是,第二个数是序列中数的范围(就是 ...