`

java String 字面值,new,intern,java8 Deduplication等

 
阅读更多

今天来总结一下String在jvm内存中的一些分配及其一些优化,包括最新的java8 update20才加入的deduplication特性,还有尚未发布的java 9中的compact特性

 

jvm中对象存在heap中,还有一块叫做String pool 的地方存放指向heap中字符串对象的指针

String s1 = "hello java";
String s2 = "hello java";
System.out.println(s1 == s2);  //true  说明s1和s2指向同一块内存地址

下面解释s1和s2的分配过程,

首先String s1 = "hello java"; ,这个是给s1分配字面值,jvm会先判断常量池中有没有引用指向堆中的一个字符串hello java,

如果没有就在堆中分配对象,然后线程堆栈的变量s1指向堆中的String对象,并且在String pool中维护一个引用指向这个String对象,

然后String s2 = "hello java",这个时候重复之前的过程,但是jvm发现常量池中已经有一个引用指向了堆中包含这个字面值的String对象,就直接在线程栈中分配了指向堆的新的引用S2,

结果如图下



 接下来看通过构造函数创建String

String s3 = new String("hello java");
System.out.println(s3 == s2);  //false  说明s3和s2 不是指向同一块内存地址

 s3是用new创建的对象,这个时候会忽略常量池中的引用,而直接在堆中新建一个对象,这种是不推荐的,下面是s3后的内存图



 


下面无论通过s3还是s1进行intern,返回的引用都是和s1相同,所以如果常量池中如果存在的话,intern返回的是引用和常量池中表记录的引用是一样的

String s4 = s3.intern();
String s5 = s1.intern();
System.out.println(s4 == s1);  //true
System.out.println(s5 == s1);  //true
//上面的图没有话,s4,s5指向的String对象和s1,s2一样

 java 8 update 20中如果加入-XX:+UseG1GC -XX:+UseStringDeduplication ,jvm将启动一个叫做Deduplication的优化,如果两个String对象中的char数组是一样的,则会回收掉其中一个,使两个对象share同一个char数组,注意必须启动java7新增的G1回收器
Deduplication和String intern不一样,前者是重用的char数组,并不会减少heap中的String对象数目
而后者可以直接重用现有的String对象
有关统计,大型java应用中25%的heap内存由String对象消耗,有近一半的String对象是重复的,也就是通过String的equals是返回true的,G1 garbage collector 会减少这种内存浪费
       
java9中新增的compcact机制可以让java中的char不要总是消耗2个byte,而是视情况而定,因为大多数情况其实一个char只需要8个bit就可以,也就是一个byte

参考如下:

http://openjdk.java.net/jeps/192

http://openjdk.java.net/jeps/254

 

后续可以通过分析字节码,利用java profile工具,分析gc log日志等方式更加细节的分析此类内存情况

  • 大小: 46.6 KB
  • 大小: 55.1 KB
分享到:
评论

相关推荐

    深入理解JavaString#intern()内存模型Ja

    深入理解JavaString#intern()内存模型Java开发Java经验技巧共4页.pdf.zip

    深入理解 Java String#intern() 内存模型.docx

    深入理解 Java String#intern() 内存模型.docx

    string常量池和intern_韩雅茹Java系列2021.pdf

    string常量池和intern_韩雅茹Java系列2021.pdf

    String类的intern、split方法

    java中String类的intern、split方法的详细讲解。

    String.intern – 字符串池

    这篇文章将要讨论 Java 6 中是如何实现 String.intern 方法的,以及这个方法在 Java 7 以及 Java 8 中做了哪些调整。

    关于java String中intern的深入讲解

    主要给大家介绍了关于java String中intern的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用java具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧

    Java String的intern用法解析

    主要介绍了Java String的intern用法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

    java String的intern方法

    本文主要介绍java 中String 的intern方法,这里主要通过实例来说明不同版本的JDK,intern方法的对比,有需要的小伙伴可以参考下

    浅谈Java String内幕(下)

    String.intern()原理  String.intern()是一个Native方法,底层调用C++的 StringTable::intern 方法,源码注释:当调用 intern 方法时,如果常量池中...  String s1 = new StringBuilder().append("String").append

    深入理解Java String#intern()内存模型

    大家知道,Java中string.intern()方法调用会先去字符串常量池中查找相应的字符串,如果字符串不存在,会在字符串常量池中创建该字符串然后再返回。  字符串常量池是一个固定大小的HashMap,桶的数量默认是1009, ...

    jdk1.8之后的String.intern()方法内存分析

    关于String.intern()方法,这个问题都被问烂了,有的文章在分析的时候还在用jdk1.7,jdk1.8之后内存模型发生了变化,内存的变化也会影响intern方法的执行,这里有必要写文章分析一下,请大家务必从头开始看,这样...

    java面试题122道基础题

    欢迎大家下载java面试题,收集的一些面试方面的题 public static void main(String[] args) { String s=new String("abc"); System.out.println(s); String s1="abc"; String s2=new String("abc"); System....

    JVM系列之String.intern的性能解析

    String对象有个特殊的StringTable字符串常量池,为了减少Heap中生成的字符串的数量,推荐尽量直接使用String Table中的字符串常量池中的元素。 那么String.intern的性能怎么样呢?我们一起来看一下。 String.intern...

    不同jdk版本下对String的intern()的分析.pos

    pos文件是ProcessOn的源文件,可以导入后直接打开编辑。 内容是:不同jdk版本下对String的intern()的分析

    C#中字符串优化String.Intern、IsInterned详解

    本文将给大家详细介绍关于C#字符串优化String.Intern、IsInterned的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧。 首先看一段程序: using System; class Program { static void ...

    【大厂面试题总结】JavaSE面试题总结详细教程

    【大厂面试题总结】JavaSE面试题总结详细教程: 目录: 递归算法之输出某个目录下所有文件和子目录列表 泛型中extends和super的区别 内部类的理解 深入理解Java的反射机制 ...string常量池和intern韩雅茹

    【大厂面试题总结】JavaSE面试题合集及其答案,基本包括javaSE所有知识点和详细解释

    【大厂面试题总结】JavaSE面试题合集及其答案,基本包括javaSE所有知识点和详细解释 。 JavaSE面试题总结详细教程: 目录: 递归算法之输出某个目录下所有文件和子目录列表 ...string常量池和intern

    提高Java代码性能的各种技巧

    Java 6,7,8中的String.intern–字符串池  这篇文章将要讨论Java 6中是如何实现String.intern方法的,以及这个方法在Java 7以及Java 8中做了哪些调整。  字符串池  字符串池(有名字符串标准化)是通过使用的...

    史上最详细的【一线大厂面试题】详解及其答案

    目录: 1、前端 2、JavaSE 3、mysql数据库 4、springboot 5、缓存 更详细目录(子目录): 1、前端目录 ①如何避免CDN为PC端缓存移动端页面 ②响应式开发剖析 ③页面渲染原理剖析 ...17、string常量池和intern

Global site tag (gtag.js) - Google Analytics