常量池与方法区以及又读new String对象创建问题
又拿出这道String str1 = new String("abc");创建几个对象的面试题梳理了一下常量池与方法区的关系,希望能把这两者的关系通过这道面试题说明白
方法区是什么
简单说方法区用于存储jvm加载的类的信息、常量、静态变量、编译后的代码
方法区、永久代与元空间的关系
下文都以HotSpot来说明
首先方法区是JVM规范的说法,永久代、元空间是HotSpot用来实现方法区的两个具体的实现
JDK1.8以前使用永久代Perm实现了JVM规范中的方法区
JDK1.8废弃永久代,变更为元空间,不是废弃了方法区
永久代与元空间的区别是元空间不在虚拟机内存中,而使用本地内存,目的是为了融合HotSpot与JRockit VM而做出的努力并且减少,并且由于这部分空间的GC效果难以令人满意
上面我们就说清楚了方法区、永久代与元空间这几个名词之间的关系和区别,下面我们在来看三个常量池的关系和不同
常量池
字符串常量池
是一个哈希表(StringTable),里面存的是驻留字符串的引用
字符串驻留:JVM 为了提高性能会将能在编译时期确定的字符串放在字符串驻留池的内存块中,String a = "abc"; String b = new String("def");都在编译时期能确定主流字符串"abc""def"
在堆中的字符串实例被这个哈希表引用之后就等同被赋予了”驻留字符串”的身份
在JVM中字符串常量池被所有类共享
字符串常量池在JDK1.7的版本从永久代移动到了堆
class文件常量池
class文件中除了包含类的版本、字段、方法、接口等描述信息外,还有一项信息就是常量池,用于存放编译器生成的各种字面量(Literal)和符号引用(Symbolic References)。注意这是class文件中的内容
字面量就是我们所说的常量概念,如文本字符串、被声明为final的常量值等
符号引用是一组符号来描述所引用的目标,符号可以是任何形式的字面量,只要使用时能无歧义地定位到目标即可,通常包含:类的全限定名、字段的名称和描述符、方法的名称和描述符
总之这些内容能表示这个类的代码内容
运行时常量池
JDK1.7仅仅把字符串常量池移动到了堆,JDK1.8虽然废弃了永久代变更为元空间,但是运行时常量池仍然跟随元空间被移出JVM内存
当类加载到内存中后,jvm就会将class常量池中的内容存放到运行时常量池中,由此可知,运行时常量池也是每个类都有一个
并且在类加载的解析阶段会把运行时常量池的符号引用替换成直接引用,这个过程需要查找字符串常量池
由上面的内容我们可知new String对象创建问题只和堆以及堆内的字符串常量池有关系(字符串常量池在不在堆对new String没什么影响)
//在堆中会有一个”abc”实例,全局StringTable中存放着”abc”的一个引用值
String str1 = "abc";
//生成两个实例,一个是”def”的实例对象,并且StringTable中存储一个”def”的引用值,还有一个是new出来的一个”def”的实例对象(指向str2)
String str2 = new String("def");
//查找StringTable,里面有”abc”的全局驻留字符串引用,所以str3的引用地址与之前的那个已存在的相同
String str3 = "abc";
//调用intern()函数,返回StringTable中”def”的引用值,如果没有就将str2的引用值添加进去
String str4 = str2.intern();
//最后str5在解析的时候就也是指向存在于StringTable中的”def”的引用值
String str5 = "def";
//生成一个实例,new出来的一个”def”的实例对象(指向str6),(def母本与StringTable放入”def”引用值已经创建)
String str6 = new String("def"); System.out.println(str1 == str3);//true System.out.println(str2 == str4);//false
System.out.println(str4 == str5);//true System.out.println(str5 == str2);//false
System.out.println(str6 == str2);//false System.out.println(str6 == str2.intern());//false
System.out.println(str6.intern() == str2.intern());//true
常量池与方法区以及又读new String对象创建问题的更多相关文章
- JDK方法区、元空间区别 & String.intern相关面试题
一.方法区.永久代.元空间 1.方法区.永久代 方法区也是各个线程共享的内存区域,它用于存储已经被虚拟机加载的类信息.常量.静态变量.即时编译器编译后的代码等数据.方法区域又被称为"永久代& ...
- jvm之java类加载机制和类加载器(ClassLoader),方法区结构,堆中实例对象结构的详解
一.类加载或类初始化:当程序主动使用某个类时,如果该类还未被加载到内存中,则JVM会通过加载.连接.初始化3个步骤来对该类进行初始化.如果没有意外,JVM将会连续完成3个步骤. 二.类加载时机: 1 ...
- 类的加载,链接和初始化——1运行时常量池(来自于java虚拟机规范英文版本+本人的翻译和理解)
加载(loading):通过一个特定的名字,找到类或接口的二进制表示,并通过这个二进制表示创建一个类或接口的过程. 链接:是获取类或接口并把它结合到JVM的运行时状态中,以让类或接口可以被执行 初始化 ...
- Java方法区和运行时常量池溢出问题分析
运行时常量池是方法区的一部分,方法区用于存放Class的相关信息,如类名.访问修饰符.常量池.字段描述.方法描述等. String.intern()是一个native方法,它的作用是:如果字符串常量池 ...
- Java方法区和运行时常量池溢出问题分析(转)
运行时常量池是方法区的一部分,方法区用于存放Class的相关信息,如类名.访问修饰符.常量池.字段描述.方法描述等. String.intern()是一个native方法,它的作用是:如果字符串常量池 ...
- 对于JVM中方法区,永久代,元空间以及字符串常量池的迁移和string.intern方法
在Java虚拟机(以下简称JVM)中,类包含其对应的元数据,比如类的层级信息,方法数据和方法信息(如字节码,栈和变量大小),运行时常量池,已确定的符号引用和虚方法表. 在过去(当自定义类加载器使用不普 ...
- Java中的栈,堆,方法区和常量池
要说Java中的栈,堆,方法区和常量池就要提到HotSpot,HotSpot是Sun JDK 和 Open JDK中所带的虚拟机. (Sun JDK 和 Open JDK除了注释不同,代码实现基本上是 ...
- String放入运行时常量池的时机与String.intern()方法解惑
运行时常量池概述 Java运行时常量池中主要存放两大类常量:字面量和符号引用.字面量比较接近于Java语言层面的常量概念,如文本字符串.声明为final的常量值等. 而符号引用则属于编译原理方面的概念 ...
- JVM体系结构之七:持久代、元空间(Metaspace) 常量池==了解String类的intern()方法、常量池介绍、常量池从Perm-->Heap
一.intern()定义及使用 相信绝大多数的人不会去用String类的intern方法,打开String类的源码发现这是一个本地方法,定义如下: public native String inter ...
随机推荐
- Bigdecimal 比较equals与compareTo
原文链接:https://blog.csdn.net/jixinhuluwa/article/details/72626598 1.b.equals(BigDecimal.ZERO); 该方法存在的问 ...
- having - 函数输出限制
引用:https://zhidao.baidu.com/question/406745181.html 对函数输出进行限制 栗子: 比如,我们可能只希望看到Store_Information数据表中销 ...
- JS事件之鼠标悬浮窗(鼠标悬浮窗抖动问题的解决)
鼠标进入显示悬浮窗,思路有简单有困难. 首先要注意的是我们要给悬浮窗设置position为absolute,不然我们改了 style.left style.top发现没有变化很尴尬.其余的内容看起来就 ...
- FTP服务器windows配置
1.配置IIS Web的FTP站点 1.1 打开iis管理器(方法很多,这里我们用命令) Win+r中输入:inetmgr 1.2 新建FTP站点 1.2.1 新建FTP服务器根目录文件夹 1.2.2 ...
- 数据库的 2个参数 NLS_LENGTH_SEMANTICS 说明,comment 说明
############### sample 1: NLS_LENGTH_SEMANTICS 1.数据库字符集选择的是NLS_CHARACTERSET=UTF8,如果NLS_CHARACTERSET= ...
- dpkg dependency problems prevent configuration
dpkg: dependency problems prevent configuration of cr3: cr3 depends on libpng12-0 (>= 1.2.13-4); ...
- CodeForces - 93B(贪心+vector<pair<int,double> >+double 的精度操作
题目链接:http://codeforces.com/problemset/problem/93/B B. End of Exams time limit per test 1 second memo ...
- (转)CentOS 6下配置软RAID图文详解
CentOS 6下配置软RAID图文详解 原文:http://blog.51cto.com/hujiangtao/1929620 一.RAID 简介 RAID 是英文Redundant Array o ...
- Spark编程模型(下)
创建Pair RDD 什么是Pair RDD 包含键值对类型的RDD类型被称作Pair RDD: Pair RDD通常用来进行聚合计算: Pair RDD通常由普通RDD做ETL转化而来. Pytho ...
- nginx开启HSTS让浏览器强制跳转HTTPS访问
在上一篇文章中我们已经实现了本地node服务使用https访问了,看上一篇文章 效果可以看如下: 但是如果我们现在使用http来访问的话,访问不了.如下图所示: 因此我现在首先要做的是使用nginx配 ...