1.//static List<Integer> list = new ArrayList<Integer>();
    public static void main(String[] args)
    {
     List<Integer> list = new ArrayList<Integer>();
     while (true) {
     list.add(256);
     }    }
2.static List<Integer> list = new ArrayList<Integer>();
    public static void main(String[] args)
    {
     //List<Integer> list = new ArrayList<Integer>();
     while (true) {
     list.add(256);
     }    }
运行这两个程序最终都是OutOfMemoryError,但是第一个会有异常信息打印出来,第二个却无声无息的终止了。
区别在于一个list是static的,另一个不是。
为什么?

解决方案 »

  1.   

    这个问题还真不清楚。
    但我猜测应该是因为静态变量与非静态变量的存储位置不同造成的。如果是全局的静态变量,那么它被保存在静态存储区。
    而在main方法里的
    List<Integer> list = new ArrayList<Integer>();,
    这个是存储在堆栈中。详情还是等楼下吧。
      

  2.   

    ????????
    我运行的时候都报异常啊?
    Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
      

  3.   

    你是怎么运行的?我在命令行和eclipse下都运行过,都是一个有异常信息一个没有。
      

  4.   

    你把GC信息log出来就知道了.
    当出现OOM时,要生成异常调用栈,而这时内存已经没有了,所以要发生FULL GC.在main方法中生成的局部变量因为main方法抛出异常,随方法帧消失也就
    失去了引用所以被回收了.下面异常调用栈可以正确地生成出来.而static的list没法被回收.内存得不到释放所以没法生成异常调用栈.
      

  5.   

    我把GC的log后半段贴出来:
    这是static的:
    0.865: [GC 56923K->56922K(65088K), 0.0149653 secs]
    0.885: [Full GC 61018K->61016K(65088K), 0.1324773 secs]
    1.032: [Full GC 65087K->65086K(65088K), 0.2000357 secs]
    1.233: [Full GC 65087K->65087K(65088K), 0.1369577 secs]
    1.370: [Full GC 65087K->65085K(65088K), 0.1928959 secs]
    1.563: [Full GC 65088K->65088K(65088K), 0.1469451 secs]
    1.710: [Full GC 65088K->65088K(65088K), 0.1368516 secs]
    1.847: [Full GC 65088K->65088K(65088K), 0.1371484 secs]
    1.984: [Full GC 65088K->65088K(65088K), 0.1370647 secs]
    2.122: [Full GC 65088K->65088K(65088K), 0.1373495 secs]
    2.259: [Full GC 65088K->65086K(65088K), 0.1955182 secs]
    这是非static的:
    0.807: [GC 56923K->56922K(65088K), 0.0148972 secs]
    0.827: [Full GC 61018K->61016K(65088K), 0.1520973 secs]
    0.993: [Full GC 65087K->65086K(65088K), 0.1624140 secs]
    1.156: [Full GC 65087K->65087K(65088K), 0.1375822 secs]
    1.294: [Full GC 65087K->65085K(65088K), 0.1967285 secs]
    1.491: [Full GC 65088K->65088K(65088K), 0.1390099 secs]
    1.630: [Full GC 65088K->65088K(65088K), 0.1386533 secs]
    1.769: [Full GC 65088K->960K(65088K), 0.0228803 secs]
    1.792: [GC 5056K->960K(65088K), 0.0000984 secs]
    可以看到非static的(也就是会打印异常调用栈的)在最后调用了一次GC,而static的没有,全是Full GC。
    axman的解释应该是对的,顺便再问一下Full GC和GC有啥不一样?
      

  6.   

    哦,收集生命周期短的区域(Young area)的收集叫 GC,而管收集生命周期比较长的区域(Old area or Tenured area)的收集叫Full GC,因为他们的收集算法不同,所以使用的时间也会不同,可以看到log里Full GC和GC差一个数量级。static变量应该是放在Tenured area的吧?在尝试了多次Full GC后就退出了。这样看来fulianglove运行的时候不是用默认的堆大小吧,所以总能打印异常。以前还有帖子说线程跑着跑着就退出了,没有异常信息打印出来,很有可能也是这个原因。