日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

分页池内存持续增长_Java技术学习之对虚拟机(JVM)内存模型的分析

發(fā)布時(shí)間:2024/9/15 java 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 分页池内存持续增长_Java技术学习之对虚拟机(JVM)内存模型的分析 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

  JVM會(huì)將Java進(jìn)程所管理的內(nèi)存劃分為若干不同的數(shù)據(jù)區(qū)域,這些區(qū)域有各自的用途、創(chuàng)建/銷毀時(shí)間。

JVM內(nèi)存數(shù)據(jù):棧管運(yùn)行,堆管存儲(chǔ)

第一章 線程私有區(qū)域

線程私有數(shù)據(jù)區(qū)域生命周期與線程相同, 依賴用戶線程的啟動(dòng)/結(jié)束而創(chuàng)建/銷毀(在Hotspot VM內(nèi), 每個(gè)線程都與操作系統(tǒng)的本地線程直接映射, 因此這部分內(nèi)存區(qū)域的存/否跟隨本地線程的生/死),下面來詳細(xì)的看看java技術(shù)。

1.1 Native Method Stack本地方法棧

是在Native Method Stack中登記native方法,在Execution Engine執(zhí)行時(shí)加載native libraies。

本地方法棧(Native Method Stacks)與虛擬機(jī)棧所發(fā)揮的作用是非常相似的,其區(qū)別不過是虛擬機(jī)棧為虛擬機(jī)執(zhí)行Java方法(也就是字節(jié)碼)服務(wù),而本地方法棧則是為虛擬機(jī)使用到的Native方法服務(wù)。虛擬機(jī)規(guī)范中對(duì)本地方法棧中的方法使用的語言、使用方式與數(shù)據(jù)結(jié)構(gòu)并沒有強(qiáng)制規(guī)定,因此具體的虛擬機(jī)可以自由實(shí)現(xiàn)它。甚至有的虛擬機(jī)(譬如Sun HotSpot虛擬機(jī))直接就把本地方法棧和虛擬機(jī)棧合二為一。與虛擬機(jī)棧一樣,本地方法棧區(qū)域也會(huì)拋出StackOverflowError和OutOfMemoryError異常。

1.2 PC Register程序計(jì)數(shù)器

每個(gè)線程都有一個(gè)程序計(jì)算器,就是一個(gè)指針,指向方法區(qū)中的方法字節(jié)碼(下一個(gè)將要執(zhí)行的指令代碼),由執(zhí)行引擎讀取下一條指令,是一個(gè)非常小的內(nèi)存空間,幾乎可以忽略不記。

作用是當(dāng)前線程所執(zhí)行字節(jié)碼的行號(hào)指示器(類似于傳統(tǒng)CPU模型中的PC), PC在每次指令執(zhí)行后自增, 維護(hù)下一個(gè)將要執(zhí)行指令的地址. 在JVM模型中, 字節(jié)碼解釋器就是通過改變PC值來選取下一條需要執(zhí)行的字節(jié)碼指令,分支、循環(huán)、跳轉(zhuǎn)、異常處理、線程恢復(fù)等基礎(chǔ)功能都需要依賴PC完成(僅限于Java方法, Native方法該計(jì)數(shù)器值為undefined)。

不同于OS以進(jìn)程為單位調(diào)度, JVM中的并發(fā)是通過線程切換并分配時(shí)間片執(zhí)行來實(shí)現(xiàn)的. 在任何一個(gè)時(shí)刻, 一個(gè)處理器內(nèi)核只會(huì)執(zhí)行一條線程中的指令. 因此, 為了線程切換后能恢復(fù)到正確的執(zhí)行位置, 每條線程都需要有一個(gè)獨(dú)立的程序計(jì)數(shù)器, 這類內(nèi)存被稱為“線程私有”內(nèi)存.

1.3 Java Stack(虛擬機(jī)棧)

棧也叫棧內(nèi)存,主管Java程序的運(yùn)行,是在線程創(chuàng)建時(shí)創(chuàng)建,它的生命期是跟隨線程的生命期,線程結(jié)束棧內(nèi)存也就釋放,對(duì)于棧來說不存在垃圾回收問題,只要線程一結(jié)束該棧就Over,生命周期和線程一致,是線程私有的。

基本類型的變量和對(duì)象的引用變量都是在函數(shù)的棧內(nèi)存中分配。

棧幀中主要保存3類數(shù)據(jù):

本地變量(Local Variables):輸入?yún)?shù)和輸出參數(shù)以及方法內(nèi)的變量;

棧操作(Operand Stack):記錄出棧、入棧的操作;

棧幀數(shù)據(jù)(Frame Data):包括類文件、方法等等。

棧運(yùn)行原理

棧中的數(shù)據(jù)都是以棧幀(Stack Frame)的格式存在,棧幀是一個(gè)內(nèi)存區(qū)塊,是一個(gè)數(shù)據(jù)集,是一個(gè)有關(guān)方法和運(yùn)行期數(shù)據(jù)的數(shù)據(jù)集,當(dāng)一個(gè)方法A被調(diào)用時(shí)就產(chǎn)生了一個(gè)棧幀F(xiàn)1,并被壓入到棧中,A方法又調(diào)用了B方法,于是產(chǎn)生棧幀F(xiàn)2也被壓入棧,B方法又調(diào)用了C方法,于是產(chǎn)生棧幀F(xiàn)3也被壓入棧…… 依次執(zhí)行完畢后,先彈出后進(jìn)......F3棧幀,再彈出F2棧幀,再彈出F1棧幀。

遵循“先進(jìn)后出”/“后進(jìn)先出”原則。

第二章 線程共享區(qū)域

隨虛擬機(jī)的啟動(dòng)/關(guān)閉而創(chuàng)建/銷毀

2.1 Method Area方法區(qū)

常說的永久代(Permanent Generation), 用于存儲(chǔ)被JVM加載的類信息、常量、靜態(tài)變量、即時(shí)編譯器編譯后的代碼等數(shù)據(jù). HotSpot VM把GC分代收集擴(kuò)展至方法區(qū), 即使用Java堆的永久代來實(shí)現(xiàn)方法區(qū), 這樣HotSpot的垃圾收集器就可以像管理Java堆一樣管理這部分內(nèi)存, 而不必為方法區(qū)開發(fā)專門的內(nèi)存管理器(永久帶的內(nèi)存回收的主要目標(biāo)是針對(duì)常量池的回收和類型的卸載, 因此收益一般很小)。

1.7和1.8的異同

不過在1.7的HotSpot已經(jīng)將原本放在永久代的字符串常量池移出

而在1.8中, 永久區(qū)已經(jīng)被徹底移除, 取而代之的是元數(shù)據(jù)區(qū)Metaspace(這一點(diǎn)在查看GC日志和使用jstat -gcutil查看GC情況時(shí)可以觀察到),與永久代不同, 如果不指定Metaspace大小, 如果方法區(qū)持續(xù)增長, VM會(huì)默認(rèn)耗盡所有系統(tǒng)內(nèi)存.

運(yùn)行時(shí)常量池

方法區(qū)的一部分. Class文件中除了有類的版本、字段、方法、接口等描述信息外,還有一項(xiàng)常量池(Constant Pool Table)用于存放編譯期生成的各種字面量和符號(hào)引用, 這部分內(nèi)容會(huì)存放到方法區(qū)的運(yùn)行時(shí)常量池中(如前面從test方法中讀到的signature信息). 但Java語言并不要求常量一定只能在編譯期產(chǎn)生, 即并非預(yù)置入Class文件中常量池的內(nèi)容才能進(jìn)入方法區(qū)運(yùn)行時(shí)常量 池, 運(yùn)行期間也可能將新的常量放入池中, 如String的intern()方法.

2.2 Heap(Java堆)

堆這塊區(qū)域是JVM中最大的,應(yīng)用的對(duì)象和數(shù)據(jù)都是存在這個(gè)區(qū)域,這塊區(qū)域也是線程共享的,也是 gc 主要的回收區(qū),一個(gè) JVM 實(shí)例只存在一個(gè)堆類存,堆內(nèi)存的大小是可以調(diào)節(jié)的。類加載器讀取了類文件后,需要把類、方法、常變量放到堆內(nèi)存中,以方便執(zhí)行器執(zhí)行,堆內(nèi)存分為三部分:

新生區(qū)

新生區(qū)是類的誕生、成長、消亡的區(qū)域,一個(gè)類在這里產(chǎn)生,應(yīng)用,最后被垃圾回收器收集,結(jié)束生命。新生區(qū)又分為兩部分:伊甸區(qū)(Eden space)和幸存者區(qū)(Survivor pace),所有的類都是在伊甸區(qū)被new出來的。幸存區(qū)有兩個(gè):0區(qū)(Survivor 0 space)和1區(qū)(Survivor 1 space)。當(dāng)伊甸園的空間用完時(shí),程序又需要?jiǎng)?chuàng)建對(duì)象,JVM的垃圾回收器將對(duì)伊甸園進(jìn)行垃圾回收(Minor GC),將伊甸園中的剩余對(duì)象移動(dòng)到幸存0區(qū)。若幸存0區(qū)也滿了,再對(duì)該區(qū)進(jìn)行垃圾回收,然后移動(dòng)到1區(qū)。那如果1去也滿了呢?再移動(dòng)到養(yǎng)老區(qū)。若養(yǎng)老區(qū)也滿了,那么這個(gè)時(shí)候?qū)a(chǎn)生Major GC(FullGCC),進(jìn)行養(yǎng)老區(qū)的內(nèi)存清理。若養(yǎng)老區(qū)執(zhí)行Full GC 之后發(fā)現(xiàn)依然無法進(jìn)行對(duì)象的保存,就會(huì)產(chǎn)生OOM異常“OutOfMemoryError”。

如果出現(xiàn)java.lang.OutOfMemoryError: Java heap space異常,說明Java虛擬機(jī)的堆內(nèi)存不夠。原因有二:

a.Java虛擬機(jī)的堆內(nèi)存設(shè)置不夠,可以通過參數(shù)-Xms、-Xmx來調(diào)整。

b.代碼中創(chuàng)建了大量大對(duì)象,并且長時(shí)間不能被垃圾收集器收集(存在被引用)。

養(yǎng)老區(qū)

養(yǎng)老區(qū)用于保存從新生區(qū)篩選出來的 JAVA 對(duì)象,一般池對(duì)象都在這個(gè)區(qū)域活躍。

永久區(qū)

永久存儲(chǔ)區(qū)是一個(gè)常駐內(nèi)存區(qū)域,用于存放JDK自身所攜帶的 Class,Interface 的元數(shù)據(jù),也就是說它存儲(chǔ)的是運(yùn)行環(huán)境必須的類信息,被裝載進(jìn)此區(qū)域的數(shù)據(jù)是不會(huì)被垃圾回收器回收掉的,關(guān)閉 JVM 才會(huì)釋放此區(qū)域所占用的內(nèi)存。

如果出現(xiàn)java.lang.OutOfMemoryError: PermGen space,說明是Java虛擬機(jī)對(duì)永久代Perm內(nèi)存設(shè)置不夠。原因有二:

a. 程序啟動(dòng)需要加載大量的第三方j(luò)ar包。例如:在一個(gè)Tomcat下部署了太多的應(yīng)用。

b. 大量動(dòng)態(tài)反射生成的類不斷被加載,最終導(dǎo)致Perm區(qū)被占滿。

說明:

Jdk1.6及之前:常量池分配在永久代 。

Jdk1.7:有,但已經(jīng)逐步“去永久代” 。

Jdk1.8及之后:無(java.lang.OutOfMemoryError: PermGen space,這種錯(cuò)誤將不會(huì)出現(xiàn)在JDK1.8中)。

說明:方法區(qū)和堆內(nèi)存的異議:

實(shí)際而言,方法區(qū)和堆一樣,是各個(gè)線程共享的內(nèi)存區(qū)域,它用于存儲(chǔ)虛擬機(jī)加載的:類信息+普通常量+靜態(tài)常量+編譯器編譯后的代碼等等,雖然JVM規(guī)范將方法區(qū)描述為堆的一個(gè)邏輯部分,但它卻還有一個(gè)別名叫做Non-Heap(非堆),目的就是要和堆分開。

對(duì)于HotSpot虛擬機(jī),很多開發(fā)者習(xí)慣將方法區(qū)稱之為“永久代(Parmanent Gen)”,但嚴(yán)格本質(zhì)上說兩者不同,或者說使用永久代來實(shí)現(xiàn)方法區(qū)而已,永久代是方法區(qū)的一個(gè)實(shí)現(xiàn),jdk1.7的版本中,已經(jīng)將原本放在永久代的字符串常量池移走。

重慶千鋒Java培訓(xùn)作為中國IT研發(fā)人才一體化服務(wù)的開拓者,為學(xué)生制定合理有序的學(xué)習(xí)計(jì)劃,0學(xué)費(fèi)入學(xué),2周免費(fèi)試聽不滿意不收費(fèi),與學(xué)員簽訂就業(yè)協(xié)議,堅(jiān)持良心面授,從千鋒重慶Java培訓(xùn)班出去的學(xué)員均已高薪就業(yè)。重慶千鋒推出的免費(fèi)Java視頻教程,讓學(xué)員能夠方面的鞏固基礎(chǔ)技術(shù)能力。了解更多的千鋒重慶java動(dòng)態(tài),不妨來實(shí)地考察一下。

總結(jié)

以上是生活随笔為你收集整理的分页池内存持续增长_Java技术学习之对虚拟机(JVM)内存模型的分析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。