詳解Java字符串在內(nèi)存中的存儲(chǔ)位置
在JDK6的時(shí)候在Java虛擬機(jī)(這里指的是HotSpot)中內(nèi)存區(qū)域分為本地方法棧、虛擬機(jī)棧、堆、程序計(jì)數(shù)器、方法區(qū)等,方法區(qū)又被稱作永久代。
這里只說(shuō)一下字符串的存儲(chǔ)位置,在Java虛擬機(jī)內(nèi)存中有個(gè)區(qū)域叫做運(yùn)行時(shí)常量池,是方法區(qū)的一部分。在JDK6中其中存放的有類的版本、字段、方法、接口等描述信息以及常量池,常量池用來(lái)存放編譯期間生成的各種字面量和符號(hào)引用,字符串就存儲(chǔ)在這個(gè)位置。下面通過(guò)代碼來(lái)看下現(xiàn)象。
這是JDK6的實(shí)驗(yàn)現(xiàn)象,Java虛擬機(jī)的配置如下:
-XX:PermSize=5M -XX:MaxPermSize=5M -Xms5M -Xmx5M -XX:-UseGCOverheadLimit -verbose:gc
其含義是方法區(qū)的初始大小為5M,最大為5M;堆空間的初始大小為5M,最大為5M,當(dāng)垃圾回收時(shí)間占的比例較高時(shí)不允許報(bào)錯(cuò),打印垃圾回收信息。
import java.util.ArrayList; import java.util.List; public class StringTest { static String base = "string"; public static void main(String[] args) { List list = new ArrayList(); for (int i = 0; i < Integer.MAX_VALUE; i++) { String str = base + base; base = str; list.add(str.intern()); } } }
運(yùn)行錯(cuò)誤如下:
可以看到報(bào)的是永久代即方法區(qū)的內(nèi)存溢出錯(cuò)誤,在這里使用了String API的inner方法,其作用是把首次遇到的字符串實(shí)例復(fù)制到永久代去,返回的也是永久代中這個(gè)字符串實(shí)例的引用。
在JDK7中字符串已經(jīng)從常量池中移除,方法區(qū)有被取消掉的趨勢(shì),在JDK7的環(huán)境下虛擬機(jī)中使用相同的配置運(yùn)行以上代碼,情況如下:
我們看到的信息是Java虛擬機(jī)堆溢出,由此可見在JDK7中字符串的存儲(chǔ)位置已經(jīng)被移到了堆中。
在JDK8的環(huán)境下,使用相同的虛擬機(jī)配置信息,就會(huì)報(bào)一個(gè)錯(cuò)誤,錯(cuò)誤如下:
指出永久代已經(jīng)在JDK8中移除。
在JDK8中新出現(xiàn)的內(nèi)存區(qū)域叫做元空間,其位于本地內(nèi)存中。我們將JDK8的虛擬機(jī)配置信息修改為如下:
-Xms5M -Xmx5M -XX:MetaspaceSize=5M -XX:MaxMetaspaceSize=5M -verbose:gc
其含義是堆內(nèi)存的初始大小為5M,最大空間為5M,元空間的初始大小為5M,最大為5M,打印垃圾回收的信息。
運(yùn)行遇上相同的代碼,打印的錯(cuò)誤信息如下:
可以看到是堆內(nèi)存溢出,在這里筆者產(chǎn)生一個(gè)疑問,因?yàn)橥ㄟ^(guò)網(wǎng)上看的資料說(shuō)的是此處應(yīng)該為元空間溢出的錯(cuò)誤,但是筆者通過(guò)實(shí)際的測(cè)試發(fā)現(xiàn),其報(bào)的錯(cuò)誤依然是堆內(nèi)存溢出的錯(cuò)誤,也就是在JDK8中字符串的存儲(chǔ)位置是堆?
因?yàn)閷?shí)驗(yàn)結(jié)果跟網(wǎng)上看到的有區(qū)別,暫且在這里打上一個(gè)問號(hào)。
以上所述是小編給大家介紹的Java字符串在內(nèi)存中的存儲(chǔ)位置詳解整合,希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
相關(guān)文章
Jmeter post上傳文件實(shí)現(xiàn)過(guò)程詳解
這篇文章主要介紹了Jmeter post上傳文件實(shí)現(xiàn)過(guò)程詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-08-08新建Maven工程出現(xiàn)Process?Terminated的問題解決
當(dāng)Maven出現(xiàn)"Process terminated"錯(cuò)誤時(shí),這通常是由于配置文件或路徑錯(cuò)誤導(dǎo)致的,本文主要介紹了新建Maven工程出現(xiàn)Process?Terminated的問題解決,感興趣的可以了解一下2024-04-04一文詳解Spring Aop @After(后置通知)的使用場(chǎng)景
@After 是 Spring AOP 中的另一種通知(Advice)類型,通常被稱為“后置通知”或“最終通知”,本文將通過(guò)詳細(xì)的代碼示例給大家介紹一下Spring Aop @After(后置通知)的使用場(chǎng)景,需要的朋友可以參考下2025-06-06JAVA使用SimpleDateFormat類表示時(shí)間代碼實(shí)例
這篇文章主要介紹了JAVA使用SimpleDateFormat類表示時(shí)間代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-04-04Spring?Security如何實(shí)現(xiàn)升級(jí)密碼加密方式詳解
這篇文章主要為大家介紹了Spring?Security實(shí)現(xiàn)升級(jí)密碼加密方式詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01MybatisPlus3.3.1整合clickhouse的過(guò)程
這篇文章主要介紹了MybatisPlus3.3.1整合clickhouse的過(guò)程,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2025-05-05java 交換兩個(gè)數(shù)據(jù)的方法實(shí)例詳解
這篇文章主要介紹了java 交換兩個(gè)數(shù)據(jù)的方法實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下2016-12-12