虚拟机运行时常量池与String的intern方法
来源:互联网 发布:5c5c5c最新域名升级 编辑:程序博客网 时间:2024/06/01 08:20
运行时常量池是方法区的一部分,存放编译期生成的字面量和符号引用,String的intern()方法在运行期间将新常量放入运行时常量池中
在程序的编译期,生成了class文件,代码中的类 ,方法,接口等的常量和字符串常量就放到class文件的常量池中。
在虚拟机加载class文加后,class文件中的常量池就被放到了运行时常量池,这个运行时常量池时方法区的一部分。
运行时常量池有大小限制,一般为4M,如果超出这个限制可能就要抛出OOM异常,往常量池中添加数据,类的加载是一种方式,还有一种用的比较多的方式是String的intern()方法。
简单来说,intern方法是拿字符串到常量池中比较,如果运行时常量池中有该字符串,则返回其引用,若没有,则将该字符串添加到运行时常量池中。
intern方法在文档中的解释:
Returns a canonical representation for the string object.
A pool of strings, initially empty, is maintained privately by the class String
.
When the intern method is invoked, if the pool already contains a string equal to thisString
object as determined by the equals(Object)
(euqal方法比较String的内容是否相同,而不比较引用是否相同)method, then the string from the pool is returned. Otherwise, thisString
object is added to the pool and a reference to this String
object is returned.
It follows that for any two strings s
and t
, s.intern() == t.intern()
istrue
if and only if s.equals(t)
is true
.
All literal strings and string-valued constant expressions are interned. String literals are defined in §3.10.5 of theJava
举一些面试中常见的例子
public class Intern {
public static void main(String[] args) {
System.out.println(System.getProperty("java.vm.version")); //打印java虚拟机版本
String s = new String("1")+“1”; //用这种方式初始化s是为了不在类加载阶段就将11放到常量池中,生成的s存放在heap中
s.intern();
String s2 = "11";
System.out.println(s == s2);
}
}
发现在不同版本的jdk上编译运行会输出不同的结果
在1.6:
在1.7:
出现两种不同结果;常量池在VM的方法区,方法区在hotspot虚拟机上一版用永久代来实现,因此也是有MaxPermSize上限的,是在jdk1.7后,为了防止常量池溢出,将常量池移到了heap区,也就是实现对象内存分配的堆内存。
如此一来,当执行s.intern()时,常量池所在区域与s对象所在区域都是heap,于是常量池保存了该字符串对象的引用s到常量池。
当生成s2时,由于常量池中已经有11字符串,直接将该引用返回,于是s2指向常量池s,也就是堆内存中s的对象,所以用==比较s与s2的地址时,返回了true。
1 0
- 虚拟机运行时常量池与String的intern方法
- jvm虚拟机运行时内存分析,堆,栈,方法区,程序计数器,本地栈,常量池
- String中的intern方法与常量池
- String.intern()方法与常量池存入时的疑惑!
- Java虚拟机运行时的数据区
- java虚拟机运行时的数据区域
- Java虚拟机运行时的数据区域
- Java String intern() 方法解析 常量池
- Java虚拟机运行时查看内存使用方式的三中方法
- 字符串常量池与intern方法
- 虚拟机运行时数据区
- jvm虚拟机运行时分析
- 简单介绍String与常量池以及String.intern()
- java虚拟机运行时的所管理的内存模型
- java虚拟机运行时数据区域及对象的探秘
- 笔记一:虚拟机运行时的数据区域
- 对于JAVA虚拟机运行时数据区的理解
- JVM虚拟机运行时数据区域的理解
- POJ 3096 Surprising Strings(水题)
- Wireshark网络抓包(二)——过滤器
- Android性能优化系列之内存优化
- 假期训练——Hangman Judge UVA - 489 模拟
- 熟练使用java的Enum、EnumSet、EnumMap
- 虚拟机运行时常量池与String的intern方法
- Android Studio 执行 lint task失败的问题
- Java基础学习总结(97)——合格的Java的架构师需要具备的技术知识
- Hyperledger fablic 1.0 在centos7环境下的安装与部署和动态增加节点
- php的CI框架的配置文件的方法
- HDU 1163 Eddy's digital Roots 【九余数定理 Or 规律(瞎搞)】
- CentOS升级Python2.7.12
- SSH项目spring版本和jdk的版本不匹配的问题
- Android Notes - 添加Copy to Clipboard的选项到分享列表中