Java程序挂掉的几种可能

 今天花了一整天在跟踪一个问题,每次感觉已经快找到原因的时候发现现象又变了,我觉得从中吸取的教训可以给大家分享一下。

为了重现这个现象,我写了一个简单的例子。在本例中,先初始化了一个map,然后用一个无限循环将一些键值对插入到map里面:

 

  1. class Wrapper {  

  2. publicstaticvoid main(String args[]) throws Exception {  

  3.             Map map = System.getProperties();  

  4.             Random r = new Random();  

  5. while (true) {  

  6.         map.put(r.nextInt(), "value");  

  7.             }  

  8.       }  

  9. }  

 

你可能也猜到了,这段代码编译执行后无法正常结束。当我用这组参数启动的话:

java-Xmx100m-XX:+UseParallelGCWrapper

我会在终端中看到Java.lang.OutOfMemoryError: GC overhead limit exceeded的异常信息。不过如果我调整一下堆大小或者是GC的类型的话,在我的Mac OS X 10.9.2 系统上用Oracle Hotspot JDK 1.7.0_45来运行,就会出现不同的情况。

比如说,我用一个较小的堆来运行这个程序,就像下面这样:

java-Xmx10m-XX:+UseParallelGCWrapper

应用程序会抛出一段大家更熟悉的错误信息然后挂掉:java.lang.OutOfMemoryError: Java heap space。

如果你换成ParallelGC以外的GC策略的话,比如说-XX:+UseConcMarkSweepGC or -XX:+UseG1GC,你将会看到由默认的异常处理器所抛出的异常,并且你看不到堆栈信息了,因为堆已经没有空间了,甚至连异常的堆栈信息都没法填充了,因此它在创建异常的时候就挂掉了:

MyPrecious:examplesvladimir$java-Xmx100m-XX:+UseConcMarkSweepGCWrapper
                        
关键字:
50000+
5万行代码练就真实本领
17年
创办于2008年老牌培训机构
1000+
合作企业
98%
就业率

联系我们

电话咨询

0532-85025005

扫码添加微信