成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

深入理解虛擬機(jī)之Java內(nèi)存區(qū)域

dance / 3483人閱讀

摘要:運(yùn)行時(shí)數(shù)據(jù)區(qū)域虛擬機(jī)在執(zhí)行程序的過(guò)程中會(huì)把它管理的內(nèi)存劃分成若干個(gè)不同的數(shù)據(jù)區(qū)域。堆虛擬機(jī)所管理的內(nèi)存中最大的一塊,堆是所有線(xiàn)程共享的一塊內(nèi)存區(qū)域,在虛擬機(jī)啟動(dòng)時(shí)創(chuàng)建。

《深入理解Java虛擬機(jī):JVM高級(jí)特性與最佳實(shí)踐(第二版》讀書(shū)筆記

1 概述

對(duì)于Java程序員來(lái)說(shuō),在虛擬機(jī)自動(dòng)內(nèi)存管理機(jī)制下,不再需要像C/C++程序開(kāi)發(fā)程序員這樣為內(nèi)一個(gè)new 操作去寫(xiě)對(duì)應(yīng)的delete/free操作,不容易出現(xiàn)內(nèi)存泄漏和內(nèi)存溢出問(wèn)題。正是因?yàn)镴ava程序員把內(nèi)存控制權(quán)利交給Java虛擬機(jī),一旦出現(xiàn)內(nèi)存泄漏和溢出方面的問(wèn)題,如果不了解虛擬機(jī)是怎樣使用內(nèi)存的,那么排查錯(cuò)誤將會(huì)是一個(gè)非常艱巨的任務(wù)。

2 運(yùn)行時(shí)數(shù)據(jù)區(qū)域

Java虛擬機(jī)在執(zhí)行Java程序的過(guò)程中會(huì)把它管理的內(nèi)存劃分成若干個(gè)不同的數(shù)據(jù)區(qū)域。

2.1 程序計(jì)數(shù)器

程序計(jì)數(shù)器是一塊較小的內(nèi)存空間,可以看作是當(dāng)前線(xiàn)程所執(zhí)行的字節(jié)碼的行號(hào)指示器。字節(jié)碼解釋器工作時(shí)通過(guò)改變這個(gè)計(jì)數(shù)器的值來(lái)選取下一條需要執(zhí)行的字節(jié)碼指令,分支、循環(huán)、跳轉(zhuǎn)、異常處理、線(xiàn)程恢復(fù)等功能都需要依賴(lài)這個(gè)計(jì)數(shù)器來(lái)完。

另外,為了線(xiàn)程切換后能恢復(fù)到正確的執(zhí)行位置,每條線(xiàn)程都需要有一個(gè)獨(dú)立的程序計(jì)數(shù)器,各線(xiàn)程之間計(jì)數(shù)器互不影響,獨(dú)立存儲(chǔ),我們稱(chēng)這類(lèi)內(nèi)存區(qū)域?yàn)椤熬€(xiàn)程私有”的內(nèi)存。

2.2 Java虛擬機(jī)棧

與程序計(jì)數(shù)器一樣,Java虛擬機(jī)棧也是線(xiàn)程私有的,它的生命周期和線(xiàn)程相同,描述的是Java方法執(zhí)行的內(nèi)存模型。

Java內(nèi)存可以粗糙的區(qū)分為堆內(nèi)存(Heap)和棧內(nèi)存(Stack),其中棧就是現(xiàn)在說(shuō)的虛擬機(jī)棧,或者說(shuō)是虛擬機(jī)棧中局部變量表部分。

局部變量表主要存放了編譯器可知的各種數(shù)據(jù)類(lèi)型、對(duì)象引用。

2.3本地方法棧

和虛擬機(jī)棧所發(fā)揮的作用非常相似,區(qū)別是: 虛擬機(jī)棧為虛擬機(jī)執(zhí)行Java方法 (也就是字節(jié)碼)服務(wù),而本地方法棧則為虛擬機(jī)使用到的Native方法服務(wù)。

2.4 堆

Java虛擬機(jī)所管理的內(nèi)存中最大的一塊,Java堆是所有線(xiàn)程共享的一塊內(nèi)存區(qū)域,在虛擬機(jī)啟動(dòng)時(shí)創(chuàng)建。此內(nèi)存區(qū)域的唯一目的就是存放對(duì)象實(shí)例,幾乎所有的對(duì)象實(shí)例以及數(shù)組都在這里分配內(nèi)存。
Java堆是垃圾收集器管理的主要區(qū)域,因此也被稱(chēng)作GC堆(Garbage Collected Heap).從垃圾回收的角度,由于現(xiàn)在收集器基本都采用分代垃圾收集算法,所以Java堆還可以細(xì)分為:新生代和老年代:在細(xì)致一點(diǎn)有:Eden空間、From Survivor、To Survivor空間等。進(jìn)一步劃分的目的是更好地回收內(nèi)存,或者更快地分配內(nèi)存。

2.5 方法區(qū)

方法區(qū)與Java堆一樣,是各個(gè)線(xiàn)程共享的內(nèi)存區(qū)域,它用于存儲(chǔ)已被虛擬機(jī)加載的類(lèi)信息、常量、靜態(tài)變量、即使編譯器編譯后的代碼等數(shù)據(jù)。

HotSpot虛擬機(jī)中方法區(qū)也常被稱(chēng)為 “永久代”,本質(zhì)上兩者并不等價(jià)。僅僅是因?yàn)镠otSpot虛擬機(jī)設(shè)計(jì)團(tuán)隊(duì)用永久代來(lái)實(shí)現(xiàn)方法區(qū)而已,這樣HotSpot虛擬機(jī)的垃圾收集器就可以像管理Java堆一樣管理這部分內(nèi)存了。但是這并不是一個(gè)好主意,因?yàn)檫@樣更容易遇到內(nèi)存溢出問(wèn)題。
相對(duì)而言,垃圾收集行為在這個(gè)區(qū)域是比較出現(xiàn)的,但并非數(shù)據(jù)進(jìn)入方法區(qū)后就“永久存在”了。

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

運(yùn)行時(shí)常量池是方法區(qū)的一部分。Class文件中除了有類(lèi)的版本、字段、方法、接口等描述信息外,還有常量池信息(用于存放編譯期生成的各種字面量和符號(hào)引用)

2.7直接內(nèi)存

直接內(nèi)存并不是虛擬機(jī)運(yùn)行時(shí)數(shù)據(jù)區(qū)的一部分,也不是虛擬機(jī)規(guī)范中定義的內(nèi)存區(qū)域,但是這部分內(nèi)存也被頻繁地使用。而且也可能導(dǎo)致OutOfMemoryError異常出現(xiàn)。

JDK1.4中新加入的NIO(New Input/Output)類(lèi),引入了一種基于通道(Channel)緩存區(qū)(Buffer) 的I/O方式,它可以直接使用Native函數(shù)庫(kù)直接分配堆外內(nèi)存,然后通過(guò)一個(gè)存儲(chǔ)在java堆中的DirectByteBuffer對(duì)象作為這塊內(nèi)存的引用進(jìn)行操作。這樣就能在一些場(chǎng)景中顯著提高性能,因?yàn)?strong>避免了在Java堆和Native堆之間來(lái)回復(fù)制數(shù)據(jù)。

本機(jī)直接內(nèi)存的分配不會(huì)收到Java堆的限制,但是,既然是內(nèi)存就會(huì)受到本機(jī)總內(nèi)存大小以及處理器尋址空間的限制。

3 HotSpot虛擬機(jī)對(duì)象探秘

通過(guò)上面的介紹我們大概知道了虛擬機(jī)的內(nèi)存情況,下面我們來(lái)詳細(xì)的了解一下HotSpot虛擬機(jī)在Java堆中對(duì)象分配、布局和訪(fǎng)問(wèn)的全過(guò)程。

3.1 對(duì)象的創(chuàng)建

虛擬機(jī)遇到一條new指令時(shí),首先將去檢查這個(gè)指令的參數(shù)是否能在常量池中定位到這個(gè)類(lèi)的符號(hào)引用,并且檢查這個(gè)符號(hào)引用代表的類(lèi)是否已被加載過(guò)、解析和初始化過(guò)。如果沒(méi)有,那必須先執(zhí)行相應(yīng)的類(lèi)加載過(guò)程。

類(lèi)加載檢查通過(guò)后,接下來(lái)虛擬機(jī)將為新生對(duì)象分配內(nèi)存。對(duì)象所需的內(nèi)存大小在類(lèi)加載完成后便可確定,為對(duì)象分配空間的任務(wù)等同于把一塊確定大小的內(nèi)存從Java堆中劃分出來(lái)。分配方式“指針碰撞”“空閑列表” 兩種,選擇那種分配方式由Java堆是否規(guī)整決定,而Java堆是否規(guī)整又由所采用的垃圾收集器是否帶有壓縮整理功能決定。

虛擬機(jī)采用CAS配上失敗重試的方式保證更新操作的原子性。

接下來(lái),虛擬機(jī)要對(duì)對(duì)象進(jìn)行必要的設(shè)置,例如這個(gè)對(duì)象是那個(gè)類(lèi)的實(shí)例、如何才能找到類(lèi)的元數(shù)據(jù)信息、對(duì)象的哈希嗎、對(duì)象的GC分代年齡等信息。這些信息存放在對(duì)象頭中,根據(jù)虛擬機(jī)當(dāng)前運(yùn)行狀態(tài)的不同,如是否啟用偏向鎖等,對(duì)象頭會(huì)與不同的設(shè)置方式。
new指令執(zhí)行完后,再按照程序員的意愿執(zhí)行init方法后一個(gè)真正可用的對(duì)象才誕生。

3.2 對(duì)象的內(nèi)存布局

在Hotspot虛擬機(jī)中,對(duì)象在內(nèi)存中的布局可以分為3快區(qū)域:對(duì)象頭實(shí)例數(shù)據(jù)對(duì)齊填充。

Hotspot虛擬機(jī)的對(duì)象頭包括兩部分信息,第一部分用于存儲(chǔ)對(duì)象自身的自身運(yùn)行時(shí)數(shù)據(jù)(哈希嗎、GC分代年齡、鎖狀態(tài)標(biāo)志等等),另一部分是類(lèi)型指針,即對(duì)象指向它的類(lèi)元數(shù)據(jù)的指針,虛擬機(jī)通過(guò)這個(gè)指針來(lái)確定這個(gè)對(duì)象是那個(gè)類(lèi)的實(shí)例。

實(shí)例數(shù)據(jù)部分是對(duì)象真正存儲(chǔ)的有效信息,也是在程序中所定義的各種類(lèi)型的字段內(nèi)容。

對(duì)齊填充部分不是必然存在的,也沒(méi)有什么特別的含義,僅僅起占位作用。 因?yàn)镠otspot虛擬機(jī)的自動(dòng)內(nèi)存管理系統(tǒng)要求對(duì)象起始地址必須是8字節(jié)的整數(shù)倍,換句話(huà)說(shuō)就是對(duì)象的大小必須是8字節(jié)的整數(shù)倍。而對(duì)象頭部分正好是8字節(jié)的倍數(shù)(1倍或2倍),因此,當(dāng)對(duì)象實(shí)例數(shù)據(jù)部分沒(méi)有對(duì)齊時(shí),就需要通過(guò)對(duì)齊填充來(lái)補(bǔ)全。

3.3對(duì)象的訪(fǎng)問(wèn)定位

建立對(duì)象就是為了使用對(duì)象,我們的Java程序通過(guò)棧上的reference數(shù)據(jù)來(lái)操作堆上的具體對(duì)象。對(duì)象的訪(fǎng)問(wèn)方式有虛擬機(jī)實(shí)現(xiàn)而定,目前主流的訪(fǎng)問(wèn)方式有①使用句柄②直接指針兩種:

如果使用句柄的話(huà),那么Java堆中將會(huì)劃分出一塊內(nèi)存來(lái)作為句柄池,reference中存儲(chǔ)的就是對(duì)象的句柄地址,而句柄中包含了對(duì)象實(shí)例數(shù)據(jù)與類(lèi)型數(shù)據(jù)各自的具體地址信息;

如果使用直接指針訪(fǎng)問(wèn),那么Java堆對(duì)像的布局中就必須考慮如何防止訪(fǎng)問(wèn)類(lèi)型數(shù)據(jù)的相關(guān)信息,reference中存儲(chǔ)的直接就是對(duì)象的地址。

這兩種對(duì)象訪(fǎng)問(wèn)方式各有優(yōu)勢(shì)。使用句柄來(lái)訪(fǎng)問(wèn)的最大好處是reference中存儲(chǔ)的是穩(wěn)定的句柄地址,在對(duì)象被移動(dòng)時(shí)只會(huì)改變句柄中的實(shí)例數(shù)據(jù)指針,而reference本身不需要修改。使用直接指針訪(fǎng)問(wèn)方式最大的好處就是速度快,它節(jié)省了一次指針定位的時(shí)間開(kāi)銷(xiāo)。

歡迎關(guān)注我的微信公眾號(hào):"Java面試通關(guān)手冊(cè)"(一個(gè)有溫度的微信公眾號(hào),期待與你共同進(jìn)步~~~堅(jiān)持原創(chuàng),分享美文,分享各種Java學(xué)習(xí)資源):

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/69247.html

相關(guān)文章

  • 深入理解虛擬機(jī)之Java內(nèi)存區(qū)域

    摘要:深入理解虛擬機(jī)高級(jí)特性與最佳實(shí)踐第二版讀書(shū)筆記與常見(jiàn)面試題總結(jié)本節(jié)常見(jiàn)面試題介紹下內(nèi)存區(qū)域運(yùn)行時(shí)數(shù)據(jù)區(qū)。運(yùn)行時(shí)數(shù)據(jù)區(qū)域虛擬機(jī)在執(zhí)行程序的過(guò)程中會(huì)把它管理的內(nèi)存劃分成若干個(gè)不同的數(shù)據(jù)區(qū)域。 《深入理解Java虛擬機(jī):JVM高級(jí)特性與最佳實(shí)踐(第二版》讀書(shū)筆記與常見(jiàn)面試題總結(jié) 本節(jié)常見(jiàn)面試題: 介紹下Java內(nèi)存區(qū)域(運(yùn)行時(shí)數(shù)據(jù)區(qū))。 對(duì)象的訪(fǎng)問(wèn)定位的兩種方式。 1 概述 對(duì)于Java...

    lavnFan 評(píng)論0 收藏0
  • 深入理解虛擬機(jī)之垃圾回收

    摘要:深入理解虛擬機(jī)高級(jí)特性與最佳實(shí)踐第二版讀書(shū)筆記與常見(jiàn)面試題總結(jié)上篇文章傳送門(mén)深入理解虛擬機(jī)之內(nèi)存區(qū)域本節(jié)常見(jiàn)面試題推薦帶著問(wèn)題閱讀,問(wèn)題答案在文中都有提到如何判斷對(duì)象是否死亡兩種方法。虛引用主要用來(lái)跟蹤對(duì)象被垃圾回收的活動(dòng)。 《深入理解Java虛擬機(jī):JVM高級(jí)特性與最佳實(shí)踐(第二版》讀書(shū)筆記與常見(jiàn)面試題總結(jié) 上篇文章傳送門(mén): 深入理解虛擬機(jī)之Java內(nèi)存區(qū)域 本節(jié)常見(jiàn)面試題(推薦帶著...

    IamDLY 評(píng)論0 收藏0
  • 深入理解虛擬機(jī)之虛擬機(jī)性能監(jiān)控和故障處理工具

    摘要:監(jiān)控和故障處理工具顯示指定系統(tǒng)內(nèi)所有的虛擬機(jī)進(jìn)程用于收集虛擬機(jī)各方面的運(yùn)行數(shù)據(jù)。的常用功能選項(xiàng)測(cè)試上面輸出了我正在運(yùn)行程序的包名下的類(lèi)名虛擬機(jī)統(tǒng)計(jì)信息監(jiān)視工具使用于監(jiān)視虛擬機(jī)各種運(yùn)行狀態(tài)信息的命令行工具。 《深入理解Java虛擬機(jī):JVM高級(jí)特性與最佳實(shí)踐(第二版》讀書(shū)筆記與常見(jiàn)面試題總結(jié) 本節(jié)常見(jiàn)面試題(推薦帶著問(wèn)題閱讀,問(wèn)題答案在文中都有提到): JVM調(diào)優(yōu)的常見(jiàn)命令行工具有哪些?...

    jas0n 評(píng)論0 收藏0
  • 深入理解虛擬機(jī)之虛擬機(jī)類(lèi)加載機(jī)制

    摘要:最終形成可以被虛擬機(jī)最直接使用的類(lèi)型的過(guò)程就是虛擬機(jī)的類(lèi)加載機(jī)制。即重寫(xiě)一個(gè)類(lèi)加載器的方法驗(yàn)證驗(yàn)證是連接階段的第一步,這一階段的目的是為了確保文件的字節(jié)流中包含的信息符合當(dāng)前虛擬機(jī)的要求,并且不會(huì)危害虛擬機(jī)自身的安全。 《深入理解Java虛擬機(jī):JVM高級(jí)特性與最佳實(shí)踐(第二版》讀書(shū)筆記與常見(jiàn)相關(guān)面試題總結(jié) 本節(jié)常見(jiàn)面試題(推薦帶著問(wèn)題閱讀,問(wèn)題答案在文中都有提到): 簡(jiǎn)單說(shuō)說(shuō)類(lèi)加載過(guò)...

    MadPecker 評(píng)論0 收藏0
  • Java】實(shí)戰(zhàn)Java虛擬機(jī)之三“G1的新生代GC”

    摘要:今天開(kāi)始實(shí)戰(zhàn)虛擬機(jī)之三的新生代。一旦區(qū)被占滿(mǎn),新生代就會(huì)啟動(dòng)。新生代收集前后的堆數(shù)據(jù)如圖所示,其中表示區(qū),表示區(qū),表示老年代。當(dāng)然我們最為關(guān)心的依然是的停頓時(shí)間以及回收情況。節(jié)選自實(shí)戰(zhàn)虛擬機(jī)一書(shū)交流群 今天開(kāi)始實(shí)戰(zhàn)Java虛擬機(jī)之三:G1的新生代GC。 總計(jì)有5個(gè)系列實(shí)戰(zhàn)Java虛擬機(jī)之一堆溢出處理實(shí)戰(zhàn)Java虛擬機(jī)之二虛擬機(jī)的工作模式實(shí)戰(zhàn)Java虛擬機(jī)之三G1的新生代GC實(shí)戰(zhàn)Java...

    BearyChat 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<