摘要:深入理解虛擬機高級特性與最佳實踐第二版讀書筆記與常見面試題總結本節常見面試題介紹下內存區域運行時數據區。運行時數據區域虛擬機在執行程序的過程中會把它管理的內存劃分成若干個不同的數據區域。
《深入理解Java虛擬機:JVM高級特性與最佳實踐(第二版》讀書筆記與常見面試題總結
本節常見面試題:
介紹下Java內存區域(運行時數據區)。
對象的訪問定位的兩種方式。
1 概述對于Java程序員來說,在虛擬機自動內存管理機制下,不再需要像C/C++程序開發程序員這樣為內一個new 操作去寫對應的delete/free操作,不容易出現內存泄漏和內存溢出問題。正是因為Java程序員把內存控制權利交給Java虛擬機,一旦出現內存泄漏和溢出方面的問題,如果不了解虛擬機是怎樣使用內存的,那么排查錯誤將會是一個非常艱巨的任務。
2 運行時數據區域Java虛擬機在執行Java程序的過程中會把它管理的內存劃分成若干個不同的數據區域。
程序計數器是一塊較小的內存空間,可以看作是當前線程所執行的字節碼的行號指示器。字節碼解釋器工作時通過改變這個計數器的值來選取下一條需要執行的字節碼指令,分支、循環、跳轉、異常處理、線程恢復等功能都需要依賴這個計數器來完。
另外,為了線程切換后能恢復到正確的執行位置,每條線程都需要有一個獨立的程序計數器,各線程之間計數器互不影響,獨立存儲,我們稱這類內存區域為“線程私有”的內存。
2.2 Java虛擬機棧與程序計數器一樣,Java虛擬機棧也是線程私有的,它的生命周期和線程相同,描述的是Java方法執行的內存模型。
Java內存可以粗糙的區分為堆內存(Heap)和棧內存(Stack),其中棧就是現在說的虛擬機棧,或者說是虛擬機棧中局部變量表部分。
局部變量表主要存放了編譯器可知的各種數據類型、對象引用。
2.3本地方法棧和虛擬機棧所發揮的作用非常相似,區別是: 虛擬機棧為虛擬機執行Java方法 (也就是字節碼)服務,而本地方法棧則為虛擬機使用到的Native方法服務。
2.4 堆Java虛擬機所管理的內存中最大的一塊,Java堆是所有線程共享的一塊內存區域,在虛擬機啟動時創建。此內存區域的唯一目的就是存放對象實例,幾乎所有的對象實例以及數組都在這里分配內存。
Java堆是垃圾收集器管理的主要區域,因此也被稱作GC堆(Garbage Collected Heap).從垃圾回收的角度,由于現在收集器基本都采用分代垃圾收集算法,所以Java堆還可以細分為:新生代和老年代:在細致一點有:Eden空間、From Survivor、To Survivor空間等。進一步劃分的目的是更好地回收內存,或者更快地分配內存。
方法區與Java堆一樣,是各個線程共享的內存區域,它用于存儲已被虛擬機加載的類信息、常量、靜態變量、即使編譯器編譯后的代碼等數據。
HotSpot虛擬機中方法區也常被稱為 “永久代”,本質上兩者并不等價。僅僅是因為HotSpot虛擬機設計團隊用永久代來實現方法區而已,這樣HotSpot虛擬機的垃圾收集器就可以像管理Java堆一樣管理這部分內存了。但是這并不是一個好主意,因為這樣更容易遇到內存溢出問題。
相對而言,垃圾收集行為在這個區域是比較出現的,但并非數據進入方法區后就“永久存在”了。
運行時常量池是方法區的一部分。Class文件中除了有類的版本、字段、方法、接口等描述信息外,還有常量池信息(用于存放編譯期生成的各種字面量和符號引用)
2.7直接內存直接內存并不是虛擬機運行時數據區的一部分,也不是虛擬機規范中定義的內存區域,但是這部分內存也被頻繁地使用。而且也可能導致OutOfMemoryError異常出現。
JDK1.4中新加入的NIO(New Input/Output)類,引入了一種基于通道(Channel) 與緩存區(Buffer) 的I/O方式,它可以直接使用Native函數庫直接分配堆外內存,然后通過一個存儲在java堆中的DirectByteBuffer對象作為這塊內存的引用進行操作。這樣就能在一些場景中顯著提高性能,因為避免了在Java堆和Native堆之間來回復制數據。
本機直接內存的分配不會收到Java堆的限制,但是,既然是內存就會受到本機總內存大小以及處理器尋址空間的限制。
3 HotSpot虛擬機對象探秘通過上面的介紹我們大概知道了虛擬機的內存情況,下面我們來詳細的了解一下HotSpot虛擬機在Java堆中對象分配、布局和訪問的全過程。
3.1 對象的創建虛擬機遇到一條new指令時,首先將去檢查這個指令的參數是否能在常量池中定位到這個類的符號引用,并且檢查這個符號引用代表的類是否已被加載過、解析和初始化過。如果沒有,那必須先執行相應的類加載過程。
在類加載檢查通過后,接下來虛擬機將為新生對象分配內存。對象所需的內存大小在類加載完成后便可確定,為對象分配空間的任務等同于把一塊確定大小的內存從Java堆中劃分出來。分配方式有 “指針碰撞” 和 “空閑列表” 兩種,選擇那種分配方式由Java堆是否規整決定,而Java堆是否規整又由所采用的垃圾收集器是否帶有壓縮整理功能決定。
虛擬機采用CAS配上失敗重試的方式保證更新操作的原子性。
接下來,虛擬機要對對象進行必要的設置,例如這個對象是那個類的實例、如何才能找到類的元數據信息、對象的哈希嗎、對象的GC分代年齡等信息。這些信息存放在對象頭中,根據虛擬機當前運行狀態的不同,如是否啟用偏向鎖等,對象頭會與不同的設置方式。
new指令執行完后,再按照程序員的意愿執行init方法后一個真正可用的對象才誕生。
在Hotspot虛擬機中,對象在內存中的布局可以分為3快區域:對象頭、實例數據和對齊填充。
Hotspot虛擬機的對象頭包括兩部分信息,第一部分用于存儲對象自身的自身運行時數據(哈希嗎、GC分代年齡、鎖狀態標志等等),另一部分是類型指針,即對象指向它的類元數據的指針,虛擬機通過這個指針來確定這個對象是那個類的實例。
實例數據部分是對象真正存儲的有效信息,也是在程序中所定義的各種類型的字段內容。
對齊填充部分不是必然存在的,也沒有什么特別的含義,僅僅起占位作用。 因為Hotspot虛擬機的自動內存管理系統要求對象起始地址必須是8字節的整數倍,換句話說就是對象的大小必須是8字節的整數倍。而對象頭部分正好是8字節的倍數(1倍或2倍),因此,當對象實例數據部分沒有對齊時,就需要通過對齊填充來補全。
3.3對象的訪問定位建立對象就是為了使用對象,我們的Java程序通過棧上的reference數據來操作堆上的具體對象。對象的訪問方式有虛擬機實現而定,目前主流的訪問方式有①使用句柄和②直接指針兩種:
如果使用句柄的話,那么Java堆中將會劃分出一塊內存來作為句柄池,reference中存儲的就是對象的句柄地址,而句柄中包含了對象實例數據與類型數據各自的具體地址信息;
如果使用直接指針訪問,那么Java堆對像的布局中就必須考慮如何防止訪問類型數據的相關信息,reference中存儲的直接就是對象的地址。
這兩種對象訪問方式各有優勢。使用句柄來訪問的最大好處是reference中存儲的是穩定的句柄地址,在對象被移動時只會改變句柄中的實例數據指針,而reference本身不需要修改。使用直接指針訪問方式最大的好處就是速度快,它節省了一次指針定位的時間開銷。
歡迎關注我的微信公眾號:"Java面試通關手冊"(一個有溫度的微信公眾號,期待與你共同進步~~~堅持原創,分享美文,分享各種Java學習資源):
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/69320.html
摘要:運行時數據區域虛擬機在執行程序的過程中會把它管理的內存劃分成若干個不同的數據區域。堆虛擬機所管理的內存中最大的一塊,堆是所有線程共享的一塊內存區域,在虛擬機啟動時創建。 《深入理解Java虛擬機:JVM高級特性與最佳實踐(第二版》讀書筆記 1 概述 對于Java程序員來說,在虛擬機自動內存管理機制下,不再需要像C/C++程序開發程序員這樣為內一個new 操作去寫對應的delete/...
摘要:深入理解虛擬機高級特性與最佳實踐第二版讀書筆記與常見面試題總結上篇文章傳送門深入理解虛擬機之內存區域本節常見面試題推薦帶著問題閱讀,問題答案在文中都有提到如何判斷對象是否死亡兩種方法。虛引用主要用來跟蹤對象被垃圾回收的活動。 《深入理解Java虛擬機:JVM高級特性與最佳實踐(第二版》讀書筆記與常見面試題總結 上篇文章傳送門: 深入理解虛擬機之Java內存區域 本節常見面試題(推薦帶著...
摘要:監控和故障處理工具顯示指定系統內所有的虛擬機進程用于收集虛擬機各方面的運行數據。的常用功能選項測試上面輸出了我正在運行程序的包名下的類名虛擬機統計信息監視工具使用于監視虛擬機各種運行狀態信息的命令行工具。 《深入理解Java虛擬機:JVM高級特性與最佳實踐(第二版》讀書筆記與常見面試題總結 本節常見面試題(推薦帶著問題閱讀,問題答案在文中都有提到): JVM調優的常見命令行工具有哪些?...
摘要:最終形成可以被虛擬機最直接使用的類型的過程就是虛擬機的類加載機制。即重寫一個類加載器的方法驗證驗證是連接階段的第一步,這一階段的目的是為了確保文件的字節流中包含的信息符合當前虛擬機的要求,并且不會危害虛擬機自身的安全。 《深入理解Java虛擬機:JVM高級特性與最佳實踐(第二版》讀書筆記與常見相關面試題總結 本節常見面試題(推薦帶著問題閱讀,問題答案在文中都有提到): 簡單說說類加載過...
摘要:今天開始實戰虛擬機之三的新生代。一旦區被占滿,新生代就會啟動。新生代收集前后的堆數據如圖所示,其中表示區,表示區,表示老年代。當然我們最為關心的依然是的停頓時間以及回收情況。節選自實戰虛擬機一書交流群 今天開始實戰Java虛擬機之三:G1的新生代GC。 總計有5個系列實戰Java虛擬機之一堆溢出處理實戰Java虛擬機之二虛擬機的工作模式實戰Java虛擬機之三G1的新生代GC實戰Java...
閱讀 1378·2021-09-24 10:26
閱讀 1689·2019-08-30 14:14
閱讀 2098·2019-08-29 16:54
閱讀 363·2019-08-29 14:09
閱讀 1468·2019-08-29 12:55
閱讀 922·2019-08-28 18:13
閱讀 1573·2019-08-26 13:39
閱讀 2560·2019-08-26 11:43