字符串常量池也是运行时常量池 jdk1.6中,它是在方法区中,属于“永久代” jdk1.7中,它被移除方法区,放在java堆中 jdk1.8中,取消了“永久代”,将常量池放在元空间,与堆独立了 public class RuntimeConstantPoolOOM { public static void main(String[] args) throws Exception{ String str1 = new StringBuffer("计算机").append("sh…
JDK7将String常量池从Perm区移动到了Java Heap区.在JDK1.6中,intern方法会把首次遇到的字符串实例复制到永久代中,返回的也是永久代中的实例.但是在JDK1.7以后,String.intern()方法不会在复制实例,只是在常量池中记录首次出现的实例引用.下面来看一些具体例子. 案例一: String str1 = new String("计算机") + new String("软件"); System.out.println(str1.i…
引言 什么都先不说,先看下面这个引入的例子: public static void test4(){ String str1 = new String("SEU") + new String("Calvin"); System.out.println(str1.intern() == str1); System.out.println(str1 == "SEUCalvin"); } 再将上面的例子加上一行代码: public static voi…
目录 1. String类是什么 1.1 定义 1.2 类结构 1.3 所在的包 2. String类的底层数据结构 3. 关于 intern() 方法(重点) 3.1 作用 3.2 字符串常量池(String Pool) 4. String类所用的连接符 5. String类的主要作用(简) 正文 1. String类是什么 1.1 定义 String类表示字符串.Java程序中的所有字符串都是这个String的实例,比如"abc".字符串为常数,它们的值在创建之后不能更改.因为字符…
1. 首先String不属于8种基本数据类型,String是一个对象. 因为对象的默认值是null,所以String的默认值也是null:但它又是一种特殊的对象,有其它对象没有的一些特性. 2. new String()和new String(“”)都是申明一个新的空字符串,是空串不是null: 3. String str=”kvill”:String str=new String (“kvill”);的区别: 在这里,我们不谈堆,也不谈栈,只先简单引入常量池这个简单的概念. 常量池(const…
ava中字符串对象创建有两种形式,一种为字面量形式,如String str = "droid";,另一种就是使用new这种标准的构造对象的方法,如String str = new String("droid");,这两种方式我们在代码编写时都经常使用,尤其是字面量的方式.然而这两种实现其实存在着一些性能和内存占用的差别.这一切都是源于JVM为了减少字符串对象的重复创建,其维护了一个特殊的内存,这段内存被成为字符串常量池或者字符串字面量池. 工作原理 当代码中出现字面…
引用自:http://blog.csdn.net/langhong8/article/details/50938041 这篇文章主要介绍了Java中的字符串常量池详细介绍,JVM为了减少字符串对象的重复创建,其维护了一个特殊的内存,这段内存被成为字符串常量池或者字符串字面量池,需要的朋友可以参考下 Java中字符串对象创建有两种形式,一种为字面量形式,如String str = "droid";,另一种就是使用new这种标准的构造对象的方法,如String str = new Stri…
转载. https://blog.csdn.net/qq_30379689/article/details/80518283 字符串常量池 JVM为了减少字符串对象的重复创建,其内部维护了一个特殊的内存,这段内存被成为字符串常量池(方法区中).实际上还有整型常量池.浮点型常量池等等.字符串常量池存放的是对象的引用,而不是对象.Java中字符串对象创建有两种形式:字面量形式和创建对象形式 1.字面量形式 字面量的体现形式String str = "Hello",简单理解为去字符串常量池中…
问题:String str = new String(“abc”),“abc”在内存中是怎么分配的?    答案是:堆内存.(Tips:jdk1.8 已经将字符串常量池放在堆内存区) 题目考查的为Java中的字符串常量池和JVM运行时数据区的相关概念. "abc"为字面量对象,其存储在堆内存中.而字符串常量池则存储的是字符串对象的一个引用. Java中的字符串常量池 Java中字符串对象创建有两种形式,一种为字面量形式,如String str = "droid";,…
在Java虚拟机(以下简称JVM)中,类包含其对应的元数据,比如类的层级信息,方法数据和方法信息(如字节码,栈和变量大小),运行时常量池,已确定的符号引用和虚方法表. 在过去(当自定义类加载器使用不普遍的时候),类几乎是“静态的”并且很少被卸载和回收,因此类也可以被看成“永久的”.另外由于类作为JVM实现的一部分,它们不由程序来创建,因为它们也被认为是“非堆”的内存. 在JDK8之前的HotSpot虚拟机中,类的这些“永久的”数据存放在一个叫做永久代的区域.永久代一段连续的内存空间,我们在JVM…
String:字符串常量池 作为最基础的引用数据类型,Java 设计者为 String 提供了字符串常量池以提高其性能,那么字符串常量池的具体原理是什么,我们带着以下三个问题,去理解字符串常量池: 字符串常量池的设计意图是什么? 字符串常量池在哪里? 如何操作字符串常量池? 字符串常量池的设计思想 字符串的分配,和其他的对象分配一样,耗费高昂的时间与空间代价,作为最基础的数据类型,大量频繁的创建字符串,极大程度地影响程序的性能 JVM为了提高性能和减少内存开销,在实例化字符串常量的时候进行了一些…
字符串常量池(String Pool)保存着所有字符串字面量(literal strings),这些字面量在编译时期就确定.不仅如此,还可以使用 String 的 intern() 方法在运行过程中将字符串添加到 String Pool 中. 当一个字符串调用 intern() 方法时,如果 String Pool 中已经存在一个字符串和该字符串值相等(使用 equals() 方法进行确定),那么就会返回 String Pool 中字符串的引用:否则,就会在 String Pool 中添加一个新…
作为最基础的引用数据类型,Java 设计者为 String 提供了字符串常量池以提高其性能,那么字符串常量池的具体原理是什么? 字符串常量池的设计思想是什么? 字符串常量池在哪里? 如何操作字符串常量池? 字符串常量池的设计思想 字符串的分配,和其他的对象分配一样,耗费高昂的时间与空间代价,作为最基础的数据类型,大量频繁的创建字符串,极大程度地影响程序的性能 JVM为了提高性能和减少内存开销,在实例化字符串常量的时候进行了一些优化 为字符串开辟一个字符串常量池,类似于缓存区 创建字符串常量时,首…
本人最近正在面试,然后注意到总是有公司喜欢考String的问题,如字符串连接有几种方式,它们之间有什么不同等问题:要不就是给一段代码问创建了几个对象.那么该不该问呢?我认为当面试有一定工作经验的求职者时还是应该问问这个问题的,应届生就不要为难他们了还是多考考底层基础比较好.下面我结合JVisualVM和javap这两个工具来详细解析下JVM内部是怎么处理String对象的. 一.字符串常量池(String Constant Pool) 字符串在java程序中被大量使用,为了避免每次都创建相同的字…
简单介绍 Java中的字符串常量池(String Pool)是存储在Java堆内存中的字符串池.我们知道String是java中比较特殊的类,我们可以使用new运算符创建String对象,也可以用双引号(”“)创建字串对象. Java中的字符串常量池 下图,清楚地解释了如何在Java堆内存中维护字符串常量池,以及当我们使用不同的方式创建字符串时在堆内存中如何存放. 之所以有字符串常量池,是因为String在Java中是不可变(immutable)的,它是String interning概念的实现…
String的基本特性 String:字符串,使用一对""引起来表示. String sl = "hello"://字面量的定义方式: String s2 = new String("hello") : String类是已经被声明为final的, 不可被继承. String实现了Serializable接口:表示字符串是支持序列化的. 实现了Comparable接口:表示String可以比较大小 String在jdk8及以前内部定义为“priva…
一.String的基本特性 String:字符串,使用一对 "" 引起来表示 String s1 = "atguigu" ; // 字面量的定义方式 String s2 = new String("hello"); // new 对象的方式 String被声明为final的,不可被继承 String实现了Serializable接口:表示字符串是支持序列化的.实现了Comparable接口:表示String可以比较大小 String在jdk8及以…
运行时常量池概述 Java运行时常量池中主要存放两大类常量:字面量和符号引用.字面量比较接近于Java语言层面的常量概念,如文本字符串.声明为final的常量值等. 而符号引用则属于编译原理方面的概念,包括了下面三类常量: - 类和接口的全限定名(包名+类名) - 字段的名称和描述符 - 方法的名称和描述符 运行时常量池位置 运行时常量池在JDK1.6及之前版本的JVM中是方法区的一部分,而在HotSpot虚拟机中方法区放在了"永久代(Permanent Generation)".所以…
运行时常量池是方法区(PermGen)的一部分. 需要提前了解: 1. JVM内存模型. 2. JAVA对象在JVM中内存分配 常量池的好处 常量池是为了避免频繁的创建和销毁对象而影响系统性能,其实现了对象的共享. - Java的自动装箱中其实就使用到了运行时常量池.详见:Java 自动装箱与拆箱的实现原理 - 还有字符串常量池. 字符串进入到常量池的两种方法: 1. new String()的实例调用intern()方法.     执行intern()方法时,若常量池中不存在等值的字符串,JV…
一.intern()定义及使用 相信绝大多数的人不会去用String类的intern方法,打开String类的源码发现这是一个本地方法,定义如下: public native String intern(); 文档告诉我们该方法返回一个字符串对象的内部化引用.关于native方法详解见native关键字(本地方法). java调用so动态链接库 java.lang.String.intern():返回一个保留池字符串,就是一个在全局字符串池中有了一个入口.如果以前没有在全局字符串池中,那么它就会…
String s1 = "Hello"; String s2 = "Hello"; String s3 = "Hel" + "lo"; String s4 = "Hel" + new String("lo"); String s5 = new String("Hello"); String s6 = s5.intern(); String s7 = "H&q…
引言 字符串常量池(StringTable)是JVM中一个重要的结构,它有助于避免重复创建相同内容的String对象.那么StringTable是怎么实现的?"把字符串加入到字符串常量池中"这个过程发生了?intern()方法又做了什么?上面的问题在JDK6和JDK7中又有什么不一样的答案? 网络上已经有海量的文章讨论过上面这些问题,但是不同的文章会给出截然相反的结论. 比如: StringTable中保存的是String对象,还是String对象的引用? new String(&qu…
1.字符串常量池 每创建一个字符串常量,JVM会首先检查字符串常量池,如果字符串已经在常量池中存在,那么就返回常量池中的实例引用.如果字符串不在池中,就会实例化一个字符串放到字符串池中.常量池提高了JVM性能和内存开销 2.用new 的方式创建字符串 new方式创建字符串,会先检查常量池中是否有相同值的字符串.如果有,则拷贝一份到堆中,然后返回堆中的地址.如果没有,则在堆中创建一份,然后返回堆中的地址. 3.String Table String Table存放的是string的cache ta…
字符串连接符 "+"及字符串常量池实验.字符串final属性 结果预览 public class StrTest{ public static void main(String[] args){ String str1="hello"; String str2="hello"+"wiaoong"; //常量 编译器直接优化为 hellowiaoong String str3=str1+"wiaoong";…
最近到广州某建站互联网公司面试,当时面试官问假设有两个字符串String a="abc",String b = "abc";问输出a==b是true还是false.我当时毫不犹豫答了true,然后根据字符串常量池的知识点结合jvm的内存模型讲解,然而他却跟我说是false,说这是最基本的问题.我当时一脸懵逼,跟他讨论了很长时间,后来发现他是错的,他说a,b两个变量是存在栈中,这两个引用是不一样的,只不过它们指向的内容是一样的.因为他毕竟工作了好几年,我当时也质疑我的…
首先看一个例子,通过这个例子更能快速理解String常量池 public static void main(String[] args) { String a = "ab"; String bb = "b"; String b = "a" + bb; String c = "a" + "b"; String d = b.intern(); System.out.println(a == b); System…
这里仅仅是举个简单的样例说明字符串常量池在内存中的位置. 闲言少叙,直接上代码. <span style="font-size: large;">import java.util.ArrayList; public class Test { public static void main(String[] args) { String str = "abc"; char[] array = {'a', 'b', 'c'}; String str2 = n…
在jdk1.6与jdk1.7中,String类中的intern()方法实现的原理是有一些差异的.1.在jdk1.6中,intern()方法是先查找字符串常量池是否含有当前字符串,如果没有,那么就在字符串常量池中创建 该字符串,并且返回该字符串在字符串常量池中的引用2.在jdk1.7中,intern()方法也是先查找字符串常量池中是否含有当前字符串,如果没有,那么就在堆中创建改字符串,并且返回该字符串在堆中的引用 这一改动会影响到相关比较的结果,一下是代码的实例 String s = new St…
老套的笔试题 在一些老套的笔试题中,会要你判断s1==s2为false还是true,s1.equals(s2)为false还是true. String s1 = new String("xyz"); String s2 = "xyz"; System.out.println(s1 == s2); System.out.println(s1.equals(s2)); 对于这种题,你总能很快的给出标准答案:==比较的是对象地址,equals方法比较的是真正的字符数组.所…
直接贴代码---> public class Test { public static void main(String[] args) { /** * 为了提升字符串的访问效率,在程序中使用了"缓存"技术 * 所以在java中用双引号括起来的字符串都会在常量池中 * 存储一次,其中字符串常量池在方法区中,在程序的执行 * 过程中,如果用到了某字符串,会先去字符串常量池中找, * 若有,则直接使用,其内存地址也相同. */ String s1 = "abc";…