java jdk1.7常量池移到哪去了?

今天模拟了一下常量池的oom,突然发现设置的参数-XX:PermSize=10M -XX:MaxPermSize=10M不管用了,同时发现内存一直在上升,当上升到一个极值就会趋于平稳,然后再过一段时间会报:
Exception in thread “main” java.lang.OutOfMemoryError: GC overhead limit exceeded
这个异常是当GC的时间超过总运行时间的98%才会报的,是为了防止GC占用的时间过长。

模拟常量池源码:

public static void main(String[] args) throws Throwable {
        List<String> list = new ArrayList<String>();
        int i=0;
        while(true){
            list.add(String.valueOf(i++).intern());
        }

    }

那么问题来了,我们从前知道的是常量池是放在Java JVM中的方法区中的,许多人也叫它“永久代”,可以通过-XX:PermSize=20M -XX:MaxPermSize=20M来设置大小,当这个区域内存溢出会报:
Exception in thread “main” java.lang.OutOfMemoryError:PermGen space的内存溢出异常,但是这里却不是那么一回事,反而GC的时间会过长,那么我猜测这个常量池是移动到了java堆中去了,下面测试一下:

首先,源代码不变,增加运行时JVM的参数:
-Xmx20m -Xms20m -XX:-UseGCOverheadLimit,这里的-XX:-UseGCOverheadLimit是关闭GC占用时间过长时会报的异常,然后限制堆的大小,运行程序,果然,一会后报异常:
Exception in thread “main” java.lang.OutOfMemoryError: Java heap space
从上面的异常可以知道我们测试增加的常量都放到了堆中,所以限制堆内存以后,不断增加常量,堆内存会溢出。和我们猜测的一样,同时我也查看了官网发现了官网有说明http://www.oracle.com/technetwork/java/javase/jdk7-relnotes-418459.html
Area: HotSpot
Synopsis: In JDK 7, interned strings are no longer allocated in the permanent generation of the Java heap, but are instead allocated in the main part of the Java heap (known as the young and old generations), along with the other objects created by the application. This change will result in more data residing in the main Java heap, and less data in the permanent generation, and thus may require heap sizes to be adjusted. Most applications will see only relatively small differences in heap usage due to this change, but larger applications that load many classes or make heavy use of the String.intern() method will see more significant differences.
RFE: 6962931

通过自己的实践和官网说明,可以知道java jdk1.7中的常量池确实是移到了堆中,同时在jdk1.8中移除整个永久代,取而代之的是一个叫元空间(Metaspace)的区域,如果想了解更多可以参考:
http://www.oracle.com/technetwork/java/javase/jdk7-relnotes-418459.html
http://blog.csdn.net/zhyhang/article/details/17246223/

  • 7
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值