Java 1.6 1.7 1.8 运行时常量池位置变化
2016-10-12 13:01
399 查看
//运行如下代码探究常量池的位置
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());
}
}
运行前首先设置永久代(PermGen)的内存大小
![](https://img-blog.csdn.net/20161012130220181?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![](https://img-blog.csdn.net/20161012130132517?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
用jdk1.6运行后会报错,永久代这个区域内存溢出会报:
Exception in thread “main” java.lang.OutOfMemoryError:PermGen space的内存溢出异常,表示永久代内存溢出。
在Java7之前,HotSpot虚拟机中将GC分代收集扩展到了方法区,使用永久代来实现了方法区。这个区域的内存回收目标主要是针对常量池的回收和对类型的卸载。但是在之后的HotSpot虚拟机实现中,逐渐开始将方法区从永久代移除。Java7中已经将运行时常量池从永久代移除,在Java 堆(Heap)中开辟了一块区域存放运行时常量池。而在Java8中,已经彻底没有了永久代,将方法区直接放在一个与堆不相连的本地内存区域,这个区域被叫做元空间。
使用jdk1.7后
验证如下:执行代码和上面相同
设置参数:-Xmx20m -Xms20m -XX:-UseGCOverheadLimit,这里的-XX:-UseGCOverheadLimit是关闭GC占用时间过长时会报的异常,然后限制堆的大小,运行程序,果然,一会后报异常:
Exception in thread “main” java.lang.OutOfMemoryError: Java heap space
从上面的异常可以知道我们测试增加的常量都放到了堆中,所以限制堆内存以后,不断增加常量,堆内存会溢出。
总结:jdk1,6常量池放在方法区,jdk1.7常量池放在堆内存,jdk1.8放在元空间里面,和堆相独立。所以导致string的intern方法因为以上变化在不同版本会有不同表现。
参考文件:http://www.aichengxu.com/view/2461897
http://blog.csdn.net/u014039577/article/details/50377805
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());
}
}
运行前首先设置永久代(PermGen)的内存大小
用jdk1.6运行后会报错,永久代这个区域内存溢出会报:
Exception in thread “main” java.lang.OutOfMemoryError:PermGen space的内存溢出异常,表示永久代内存溢出。
在Java7之前,HotSpot虚拟机中将GC分代收集扩展到了方法区,使用永久代来实现了方法区。这个区域的内存回收目标主要是针对常量池的回收和对类型的卸载。但是在之后的HotSpot虚拟机实现中,逐渐开始将方法区从永久代移除。Java7中已经将运行时常量池从永久代移除,在Java 堆(Heap)中开辟了一块区域存放运行时常量池。而在Java8中,已经彻底没有了永久代,将方法区直接放在一个与堆不相连的本地内存区域,这个区域被叫做元空间。
使用jdk1.7后
验证如下:执行代码和上面相同
设置参数:-Xmx20m -Xms20m -XX:-UseGCOverheadLimit,这里的-XX:-UseGCOverheadLimit是关闭GC占用时间过长时会报的异常,然后限制堆的大小,运行程序,果然,一会后报异常:
Exception in thread “main” java.lang.OutOfMemoryError: Java heap space
从上面的异常可以知道我们测试增加的常量都放到了堆中,所以限制堆内存以后,不断增加常量,堆内存会溢出。
总结:jdk1,6常量池放在方法区,jdk1.7常量池放在堆内存,jdk1.8放在元空间里面,和堆相独立。所以导致string的intern方法因为以上变化在不同版本会有不同表现。
参考文件:http://www.aichengxu.com/view/2461897
http://blog.csdn.net/u014039577/article/details/50377805
相关文章推荐
- jdk1.6 1.7 1.8 运行时常量池位置的变化
- jdk1.6 1.7 1.8 运行时常量池位置的变化
- 安装jdk1.8后,修改%JAVA_HOME%为jdk1.6的路径,但运行java -version没有变化
- java jdk1.7运行时常量池内存不足抛异常的位置研究
- JDK1.5/1.6/1.7/1.8 java.util下的集合类底层实现的变化
- Java 1.5,1.6,1.7,1.8新特性
- Java 1.5, 1.6, 1.7, 1.8的区别
- java JDK JRE 1.6,1.7,1.8各个版本版本下载链接
- Java 1.5,1.6,1.7,1.8新特性
- Java 1.5,1.6,1.7,1.8新特性整理
- 牛客网Java刷题知识点之HashMap的实现原理、HashMap的存储结构、HashMap在JDK1.6、JDK1.7、JDK1.8之间的差异以及带来的性能影响
- JDK1.6 1.7 1.8 多版本windows安装 执行命令java -version 版本不变的问题
- Java1.6,1.7,1.8新特性
- Java 1.5,1.6,1.7,1.8新特性
- java JDK JRE 1.6,1.7,1.8各个版本版本下载链接
- 黑马程序员-java基础加强_jdk1.6与1.7
- JAVA帮助文档全系列 JDK1.5 JDK1.6 JDK1.7 官方中英完整版下载
- JAVA帮助文档全系列 JDK1.5 JDK1.6 JDK1.7 官方中英完整版下载
- 命令行Dos下编译、运行java文件是出现has value '1.4', but '1.6' is required.错误
- JAVA帮助文档全系列 JDK1.5 JDK1.6 JDK1.7 官方中英完整版下载