电竞比分网-中国电竞赛事及体育赛事平台

分享

從String.intern()深入理解JVM

 liang1234_ 2019-01-24

代碼分析:

官方說(shuō)明翻譯:1.返回字符串對(duì)象的規(guī)范表示

2.字符串s調(diào)用intern時(shí),如果常量池中有對(duì)象t滿(mǎn)足t.equals(s)==true,則返回t的地址;否則,將s的引用(即地址)加入常量池并返回s的引用

3.s.intern()==t.intern()的充分必要條件是s.equals(t)==true

注意:1.jdk1.6及以前版本的運(yùn)行時(shí)常量池在方法區(qū)中,jdk1.7及以后版本的運(yùn)行時(shí)常量池在堆中。
2.jdk1.6及以前版本會(huì)將字符串拷貝一份到運(yùn)行時(shí)常量池,返回常量池中地址,jdk1.7及以后將堆上的地址引用復(fù)制到常量池,返回該引用地址。在此討論jdk1.7及以后版本。

一:

  1. String s1=new String("GY");
  2. System.out.println(s1.intern()==s1);//false



如果常量池中有字符串對(duì)象"GY",則new String("GY")只創(chuàng)建一個(gè)堆中的對(duì)象;如果常量池中沒(méi)有字符串對(duì)象"GY",則先在常量池中創(chuàng)建"GY",再在堆中生成一個(gè)String對(duì)象,共兩個(gè)。

二:

  1. String s1=new String("GY")+new String("HAPPY");//生成三個(gè)對(duì)象,兩個(gè)在常量池,一個(gè)在JVM堆中
  2. System.out.println(s1.intern()==s1);//true



String s1=new String("GY")+new String("HAPPY)并沒(méi)有在運(yùn)行時(shí)常量池中生成“GYHAPPY"對(duì)象,調(diào)用s1.intern()時(shí),發(fā)現(xiàn)常量池中沒(méi)有,則將對(duì)象的引用加入到池中,返回該引用(即s1地址)。

三:

詭異現(xiàn)象:

  1. String s1=new String("1")+new String("1");
  2. System.out.println(s1.intern()==s1);//false
  1. String s1=new String("ja")+new String("va");
  2. System.out.println(s1.intern()==s1);//false

這是因?yàn)镴VM加載過(guò)程中已經(jīng)在常量池中生成了"11","java"這些對(duì)象,因此intern函數(shù)返回的是常量池的地址。

底層實(shí)現(xiàn):

1.JAVA調(diào)用C++實(shí)現(xiàn)的StringTable的intern方法,原理與JAVA中的HashMap差不多,都是用鏈表法解決Hash沖突。jdk1.6以前StringTable長(zhǎng)度固定為1009,如果常量池中String很多,則鏈表很長(zhǎng),導(dǎo)致查找效率低。jdk1.7的StringTable長(zhǎng)度可設(shè)置,-XX:StringTableSize=XXXXXX。
2.一旦常量池中的字符串達(dá)到的一定的規(guī)模后,性能會(huì)急劇下降。


    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶(hù)發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶(hù) 評(píng)論公約

    類(lèi)似文章 更多