那么问题来了,我们从前知道的是常量池是放在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