一个关于String的疑问

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在运行时有逃逸分析的优化?
所以我上面的测试代码可能就并没有不断的创建新的对象。
栈上分配,同步消除,标量替换
要知道经过标量替换,就不会生成新的对象了...
抑或是别的原因? 有时间再来验证。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 195,980评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,422评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,130评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,553评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,408评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,326评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,720评论 3 386
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,373评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,678评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,722评论 2 312
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,486评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,335评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,738评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,009评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,283评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,692评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,893评论 2 335

推荐阅读更多精彩内容