国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

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

dance / 3468人閱讀

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

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

1 概述

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

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

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

2.1 程序計數(shù)器

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

另外,為了線程切換后能恢復(fù)到正確的執(zhí)行位置,每條線程都需要有一個獨立的程序計數(shù)器,各線程之間計數(shù)器互不影響,獨立存儲,我們稱這類內(nèi)存區(qū)域為“線程私有”的內(nèi)存。

2.2 Java虛擬機棧

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

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

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

2.3本地方法棧

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

2.4 堆

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

2.5 方法區(qū)

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

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

2.6 運行時常量池

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

2.7直接內(nèi)存

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

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

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

3 HotSpot虛擬機對象探秘

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

3.1 對象的創(chuàng)建

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

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

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

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

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

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

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

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

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

3.3對象的訪問定位

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

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

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

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

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

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

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/69247.html

相關(guān)文章

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

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

    lavnFan 評論0 收藏0
  • 深入理解虛擬機之垃圾回收

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

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

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

    jas0n 評論0 收藏0
  • 深入理解虛擬機之虛擬機類加載機制

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

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

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

    BearyChat 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<