最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

通過String.intern()方法淺談堆中常量池

 更新時間:2019年06月14日 14:46:40   作者:宸小朔  
這篇文章主要介紹了通過String.intern()方法淺談堆中常量池,在JDK7之前,字符串常量是存在永久帶Perm 區(qū)的,JDK7開始在將常量池遷移到堆中,這個變化也導致了String的新特性,下面我們慢慢進行介紹。,需要的朋友可以參考下

簡介

String是我們最常用的一個類,和普通java類一樣其對象會存在java堆中。但是String類有其特殊之處,可以通過new方法生成,也可以通過帶引號的字符串常量直接賦值。在JDK7之前,字符串常量是存在永久帶Perm 區(qū)的,JDK7開始在將常量池遷移到堆中,這個變化也導致了String的新特性,下面我們慢慢進行介紹。

String.intern()方法

簡單的說,String.intern()方法的作用就是返回常量池中字符串對象,在對該方法進行詳解之前,我們看幾個創(chuàng)建字符串對象的例子。以下說明及運行結(jié)果都是以JDK8為java環(huán)境。

(1)直接賦值字符串常量

​ 這種方式會判斷常量池中是否存在字符串常量,如果存在返回該常量對象,否則在常量池中創(chuàng)建常量對象并返回。

//在常量池中創(chuàng)建常量“abc”,s1,s2指向常量池中對象地址 
String s1 = "abc";
String s2 = "abc";
System.out.println(s1 == s2);//true

(2)通過new關鍵字創(chuàng)建

​ 這種方式會在堆上創(chuàng)建String對象,如果常量池中沒有該常量,將常量加入常量池中。

//在堆上創(chuàng)建對象S3,S4,常量池中創(chuàng)建對象“abc”
String s3 = new String("abc");
String s4 = new String("abc");
System.out.println(s3 == s4);//false

(3)字符串常量相加

這種方式如s5,會在常量池中創(chuàng)建"cd","ef","cdef"三個對象,s5指向常量池中的"cdef"對象。

String s5 = "cd" + "ef";
String s6 = "cdef";
System.out.println(s5==s6);//true

(4)兩個new的String對象相加

這種方式如s7,會在堆中創(chuàng)建三個對象"gh"對象,"lm"對象,以及"ghlm"對象,在常量池中創(chuàng)建對象"gh","lm"。

String s7 = new String("gh") + new String("lm");
String s8 = "ghlm";
System.out.println(s7==s8);//false

(5)字符串常量與new的String對象相加

這種方式如s9,會在堆中創(chuàng)建兩個對象“op”,“mnop”,并將字符串常量“op”, "mn"加到常量池中。

String s9 = "mn" + new String("op");
String s10 = "mnop";
System.out.println(s9==s10);//false

了解字符串常量的創(chuàng)建及其在內(nèi)存中的存儲,我們看native方法intern()的作用:判斷String對象的常量值是否存在于常量池中,如果存在并且是常量池對象,返回該常量池對象;如果存在并且是指向堆中的對象,返回堆中對象地址;如果不存在,則將對象的引用復制到常量池,并返回該對象的引用。下面我們看幾條語句的運行結(jié)果,第一個輸出之所以為true,

String s11 = new String("a") + new String("a");
s11.intern();//由于常量池中無“aa”,因此在常量池中建“aa”的引用,指向堆中的s11
String s12 = "aa";//s12指向常量池中的對象(該對象指向S11)
System.out.println(s11 == s12.intern());//true
String s13 = new String("b");
s13.intern();//常量池中已經(jīng)有“b”了,不做任何操作
String s14 = "b";
System.out.println(s13==s14.intern());//false

如果理解了以上運行的結(jié)果,對intern()方法的左右就掌握的差不多了。那么久可以開始我們的主題,string pool,字符串常量池。

字符串常量池

字符串常量池是jvm為了減小內(nèi)存開銷而在創(chuàng)建字符串對象時的一個優(yōu)化,類似緩沖區(qū)。在hotspot中,字符串常量池是一個叫做StringTable的HashTable,默認長度是1009,在JDK7開始可以通過"-XX:StringTableSize=1009" 參數(shù)來設置,字符串常量池數(shù)據(jù)可以被gc回收(在JDK6及其以前,字符串常量存在永久帶無法被gc回收,如果添加太多字符串常量到該區(qū)域,容易發(fā)生OOM)。由于字符串常量池是利用HashTable實現(xiàn),因此一定會發(fā)生hash碰撞。

jvm在這方面做了一定優(yōu)化,會根據(jù)hashTable的碰撞情況來決定是否做rehash,當從這個StringTable里查找某個字符串是否存在,如果對其對應的桶鏈表進行遍歷,遍歷超過了100個節(jié)點還是沒有找到,那就會設置一個flag,讓下次進入到safepoint的時候做一次rehash動作,盡量減少碰撞的發(fā)生。當然,在數(shù)據(jù)量比較大的情況下,這也無法從根本上解決問題,只能設置StringTableSize的值來緩解。

由于JDK7開始字符串常量池在堆中分布,所以young gc過程會掃描該區(qū)域,以保證處于新生代的String對象不會被回收掉,因此如果字符串常量區(qū)非常龐大會導致young gc過程掃描的時間也會變長。但是,young gc階段并不會對字符串常量區(qū)進行回收,具體回收階段是在Full gc或者CMS gc階段(題外話:我覺得full gc這個名字并不是很好,容易理解為對所有區(qū)域進行回收,其實full GC是對老年代的STW的gc,full gc的次數(shù)是老年代gc的STW次數(shù),時間是老年代STW的總時間)。

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

  • SpringCloud的Gateway網(wǎng)關詳解

    SpringCloud的Gateway網(wǎng)關詳解

    這篇文章主要介紹了SpringCloud的Gateway網(wǎng)關詳解,Gateway 是 Spring Cloud 官方推出的一個基于 Spring 5、Spring Boot 2 和 Project Reactor 的 API 網(wǎng)關實現(xiàn),本文將介紹 Spring Cloud Gateway 的基本概念、核心組件以及如何配置和使用它,需要的朋友可以參考下
    2023-09-09
  • Android Studio更改項目使用的JDK(詳細步驟)

    Android Studio更改項目使用的JDK(詳細步驟)

    本文介紹了如何在Android Studio中修改Gradle和JDK的配置步驟,包括打開設置、進入Gradle設置、修改JDK路徑、保存并生效等,感興趣的朋友跟隨小編一起看看吧
    2024-11-11
  • netty對proxy protocol代理協(xié)議的支持詳解

    netty對proxy protocol代理協(xié)議的支持詳解

    這篇文章主要為大家介紹了netty對proxy protoco代理協(xié)議的支持詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-07-07
  • 淺談Java 中的單元測試

    淺談Java 中的單元測試

    這篇文章主要介紹了Java 中的單元測試的相關資料,幫助大家更好的理解和使用Java,感興趣的朋友可以了解下
    2020-09-09
  • mybatis的動態(tài)SQL以及連接池詳解

    mybatis的動態(tài)SQL以及連接池詳解

    這篇文章主要介紹了mybatis的動態(tài)SQL以及連接池詳解,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • java實現(xiàn)字符串轉(zhuǎn)String數(shù)組的方法示例

    java實現(xiàn)字符串轉(zhuǎn)String數(shù)組的方法示例

    這篇文章主要介紹了java實現(xiàn)字符串轉(zhuǎn)String數(shù)組的方法,涉及java字符串的遍歷、分割、轉(zhuǎn)換等相關操作技巧,需要的朋友可以參考下
    2017-10-10
  • 通俗易懂的Java常見限流算法具體實現(xiàn)

    通俗易懂的Java常見限流算法具體實現(xiàn)

    這篇文章主要介紹了Java常見限流算法具體實現(xiàn)的相關資料,包括漏桶算法、令牌桶算法、Nginx限流和Redis+Lua限流的實現(xiàn)原理和具體步驟,并比較了它們的優(yōu)點和缺點,需要的朋友可以參考下
    2025-02-02
  • Spring框架學習常用注解匯總

    Spring框架學習常用注解匯總

    這篇文章主要為大家介紹了Spring框架學習中一些經(jīng)常用的注解匯總及示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步
    2021-10-10
  • Java中?springcloud.openfeign應用案例解析

    Java中?springcloud.openfeign應用案例解析

    使用OpenFeign能讓編寫Web?Service客戶端更加簡單,使用時只需定義服務接口,然后在上面添加注解,OpenFeign也支持可拔插式的編碼和解碼器,這篇文章主要介紹了Java中?springcloud.openfeign應用案例解析,需要的朋友可以參考下
    2024-06-06
  • mybatis空值插入處理的解決方法

    mybatis空值插入處理的解決方法

    本文主要介紹了mybatis空值插入處理的解決方法,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-09-09

最新評論

凤凰县| 清苑县| 许昌市| 六盘水市| 米林县| 衡南县| 民县| 安阳市| 易门县| 梓潼县| 虎林市| 台湾省| 红安县| 施甸县| 汪清县| 新巴尔虎左旗| 山丹县| 乌兰浩特市| 贺州市| 积石山| 斗六市| 通山县| 上蔡县| 佛山市| 金塔县| 上林县| 通河县| 谢通门县| 赣榆县| 南江县| 建昌县| 宜黄县| 牟定县| 五寨县| 通榆县| 宣恩县| 桓仁| 满洲里市| 西峡县| 灵璧县| 图们市|