美文网首页
一个关于String的疑问

一个关于String的疑问

作者: mrz_233333 | 来源:发表于2018-03-30 11:26 被阅读0次

java里,String是本质还是一个immutable的对象,其值具体是由String类里的一个final char数组表示

private final char value[];

看了JDK源码才发现定义一个数组可以char[] value,也可以char value[]

参考:https://javaranch.com/journal/200409/ScjpTipLine-StringsLiterally.html

1

当执行:


image.png

内存引用关系是这样的:


image.png

2

当执行:


image.png

内存引用关系是这样的:


image.png

3

当执行:


image.png

内存引用关系是这样的:


image.png

而且文中关于垃圾收集:

Unlike most objects, String literals always have a reference to them 
from the String Literal Pool. That means that they always have a 
reference to them and are, therefore, not eligible for garbage collection. 

不同于大多数对象,String总有一个来自于String常量池(String Literal Pool?)的引用,这意味着,String对象们总有一个引用持有着他们,因此不能被垃圾回收。
ok,既然定义一个不同的String就会在常量池中创建一个对堆中string的引用,并使得这个string对象很大程度上不被垃圾回收。

那么问题来了:不断地创建不同的String,是不是就撑爆了heap?:

    static int i;
    public static void test(){
        String c = "hello worldddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd";
        while (true){
            String b = c+i;
            i++;
            System.out.println(b);
        }

    }

很明显我尝试了,并没有,执行到2亿次,也没有..
使用visualJVM来查看:

image.png
查看metaspace,metaspace是jdk1.8之后增加的一个非heap的空间。
参考:https://segmentfault.com/a/1190000012577387
方法区移动到metaspace,constant pool似乎在heap?
image.png

不管是heap,还是metaspace,内存似乎并没有显著平稳增加。
那么在进行字符串拼接的时候(“+”号运算符),到底发生了什么,到底有没有创建新的字符串到constant pool?

image.png
Debug一下,总所周知,“+”号拼接字符串其实被编译为了StringBuilder进行拼接,debug结果显示的也是如此。看来采用StringBuilder并没有在常量池里创建多个String对象... 真的是如此吗?dump heap查看一下
首先用jps工具查出进程的vmid:
image.png
(这里发现jdk提供的工具检测还是挺多的,还有jstat 查看jvm的各种状态,一个简单用法是jstat -snap vmid 见R大blog:http://rednaxelafx.iteye.com/blog/796343)
vmid为5430,接着dump heap:
image.png
ok,分析一下hprof文件,看看到底有多少String:
image.png
可以看到拼接了快750w次,String还只有1000个,其他都是jvm的路径之类的String,真正存在在内存里的似乎只有最后一个被拼接的String。。

看来在进行拼接的时候还是进行了某些特殊的处理,代码有些分析不出来个所以然,猜测可能是jit在运行时有逃逸分析的优化?
所以我上面的测试代码可能就并没有不断的创建新的对象。
栈上分配,同步消除,标量替换
要知道经过标量替换,就不会生成新的对象了...
抑或是别的原因? 有时间再来验证。

相关文章

  • 一个关于String的疑问

    java里,String是本质还是一个immutable的对象,其值具体是由String类里的一个final ch...

  • java String、StringBuffer与StringB

    最近学习到StringBuffer,心中有好些疑问,搜索了一些关于String,StringBuffer,Stri...

  • String-hashcode疑问

    今天闲来没事看String的源码,在看到hashCode方法里的实现,总感觉有点问题,以前就是看看了实现并没有太在...

  • Java学习19:String类、StringBuffer类

    String类 关于Java JDK中内置的一个类:java.lang.String String表示字符串类型,...

  • JavaSE进阶-04-常用类

    String 关于Java JDK中内置的一个类:java.lang.String1.String表示字符串类型,...

  • 关于String内的indexOf方法的一些疑问

    今天浏览了一下java里的String类,发现一个静态方法有点意思,就是我们常用的indexOf(String s...

  • 一个关于PCA的疑问

    一个关于PCA的疑问 我们知道PCA干的事情是把n维的样本投影到k维,同时丢失的信息能够达到最少。 为什么说pri...

  • 一个关于hessian的疑问

    hessian是一个java序列化库。dubbo底层用这个库序列化java对象。hessian序列化需要实现Ser...

  • Android AES 加密

    关于加密解密时的String与byte[]转换:明文String<-->明文byte[]:String.getBy...

  • 关于 String

    1. String 不可变 不可变对象对象在创建完成之后,其状态不能再被改变,则该对象即为不可变对象 对象不可变具...

网友评论

      本文标题:一个关于String的疑问

      本文链接:https://www.haomeiwen.com/subject/vxducftx.html