摘要:運行時數(shù)據(jù)區(qū)域的學(xué)習(xí),是學(xué)習(xí)以及機制的基礎(chǔ),也是深入理解對象創(chuàng)建及運行過程的前提。了解內(nèi)存區(qū)域劃分,是學(xué)習(xí)概念的前提。
Java 運行時數(shù)據(jù)區(qū)域的學(xué)習(xí),是學(xué)習(xí) jvm 以及 GC 機制的基礎(chǔ),也是深入理解 java 對象創(chuàng)建及運行過程的前提。
廢話不多說,直接進入正題:
程序計數(shù)器是一個比較小的內(nèi)存區(qū)域,用于指示當(dāng)前線程所執(zhí)行的字節(jié)碼執(zhí)行到了第幾行,可以理解為是當(dāng)前線程的行號指示器。字節(jié)碼解釋器在工作時,會通過改變這個計數(shù)器的值來取下一條語句指令。
作用由于 Java 虛擬機的多線程是通過線程輪流切換并分配處理器執(zhí)行時間的方式來實現(xiàn)的,在任何一個確定的時刻,一個處理器(嚴謹點,多核處理器時指其中一個內(nèi)核),只會執(zhí)行一條線程的指令。
因此,為了實現(xiàn)線程切換后回復(fù)到正確的執(zhí)行位置,各個線程私有的程序計數(shù)器時必不可少的。
注: 如果程序執(zhí)行的是一個Java方法,則計數(shù)器記錄的是正在執(zhí)行的虛擬機字節(jié)碼指令地址;如果正在執(zhí)行的是一個本地(native,由C語言編寫完成)方法,則計數(shù)器的值為Undefined
另: 由于程序計數(shù)器只是記錄當(dāng)前指令地址,所以不存在內(nèi)存溢出的情況,因此,程序計數(shù)器也是所有JVM內(nèi)存區(qū)域中唯一一個沒有定義OutOfMemoryError的區(qū)域。
Java 虛擬機棧 概念一個線程的每個方法在執(zhí)行的同時,都會創(chuàng)建一個棧幀(Statck Frame),棧幀中存儲的有局部變量表、操作站、動態(tài)鏈接、方法出口等,當(dāng)方法被調(diào)用時,棧幀在JVM棧中入棧,當(dāng)方法執(zhí)行完成時,棧幀出棧。
作用局部變量表中存儲著方法的相關(guān)局部變量,包括各種基本數(shù)據(jù)類型,對象的引用,返回地址等。在局部變量表中,只有l(wèi)ong和double類型會占用2個局部變量空間(Slot,對于32位機器,一個Slot就是32個bit),其它都是1個Slot。
需要注意的是,局部變量表是在編譯時就已經(jīng)確定好的,方法運行所需要分配的空間在棧幀中是完全確定的,在方法的生命周期內(nèi)都不會改變。
注: 每個線程對應(yīng)著一個虛擬機棧,因此虛擬機棧也是線程私有的。
另: 虛擬機棧中定義了兩種異常,如果線程調(diào)用的棧深度大于虛擬機允許的最大深度,則拋出StatckOverFlowError(棧溢出);不過多數(shù)Java虛擬機都允許動態(tài)擴展虛擬機棧的大小(有少部分是固定長度的),所以線程可以一直申請棧,直到內(nèi)存不足,此時,會拋出OutOfMemoryError(內(nèi)存溢出)。
本地方法棧本地方法棧在作用,運行機制,異常類型等方面都與虛擬機棧相同,唯一的區(qū)別是:虛擬機棧是執(zhí)行Java方法的,而本地方法棧是用來執(zhí)行native方法的,在很多虛擬機中(如Sun的JDK默認的HotSpot虛擬機),會將本地方法棧與虛擬機棧放在一起使用。
本地方法棧也是線程私有的。
Java 堆 概念JVM用來存儲對象實例以及數(shù)組值的區(qū)域,可以認為Java中所有通過new創(chuàng)建的對象的內(nèi)存都在此分配,Heap中的對象的內(nèi)存需要等待GC進行回收(不過現(xiàn)代技術(shù)里,也不是這么絕對的,也有棧上直接分配的)。
補充介紹(1)堆是JVM中所有線程共享的,因此在其上進行對象內(nèi)存的分配均需要進行加鎖,這也導(dǎo)致了new對象的開銷是比較大的
(2)Sun Hotspot JVM為了提升對象內(nèi)存分配的效率,對于所創(chuàng)建的線程都會分配一塊獨立的空間TLAB(Thread Local Allocation Buffer),其大小由JVM根據(jù)運行的情況計算而得,在TLAB上分配對象時不需要加鎖,因此JVM在給線程的對象分配內(nèi)存時會盡量的在TLAB上分配,在這種情況下JVM中分配對象內(nèi)存的性能和C基本是一樣高效的,但如果對象過大的話則仍然是直接使用堆空間分配
(3)TLAB僅作用于新生代的Eden Space,因此在編寫Java程序時,通常多個小的對象比大的對象分配起來更加高效。
關(guān)于堆區(qū)的內(nèi)容還有很多,在后續(xù)的垃圾回收算法中還有更多的介紹。
方法區(qū) 概念方法區(qū)是各個線程共享的區(qū)域,用于存儲已經(jīng)被虛擬機加載的類信息(即加載類時需要加載的信息,包括版本、field、方法、接口等信息)、final常量、靜態(tài)變量、編譯器即時編譯的代碼等。
補充介紹方法區(qū)在物理上也不需要是連續(xù)的,可以選擇固定大小或可擴展大小,并且方法區(qū)比堆還多了一個限制:可以選擇是否執(zhí)行垃圾收集。一般的,方法區(qū)上執(zhí)行的垃圾收集是很少的,這也是方法區(qū)被稱為永久代的原因之一(HotSpot),但這也不代表著在方法區(qū)上完全沒有垃圾收集,其上的垃圾收集主要是針對常量池的內(nèi)存回收和對已加載類的卸載。
在方法區(qū)上定義了OutOfMemoryError:PermGen space異常,在內(nèi)存不足時拋出。
運行時常量池 概念方法區(qū)的一部分,用于存儲編譯期就生成的字面常量、符號引用、翻譯出來的直接引用(符號引用就是編碼是用字符串表示某個變量、接口的位置,直接引用就是根據(jù)符號引用翻譯出來的地址,將在類鏈接階段完成翻譯);運行時常量池除了存儲編譯期常量外,也可以存儲在運行時間產(chǎn)生的常量(比如String類的intern()方法,作用是String維護了一個常量池,如果調(diào)用的字符“abc”已經(jīng)在常量池中,則返回池中的字符串地址,否則,新建一個常量加入池中,并返回地址)
總結(jié)本系列文章將從4個方面介紹Java GC機制,1,內(nèi)存是如何分配的;2,如何保證內(nèi)存不被錯誤回收(即:哪些內(nèi)存需要回收);3,在什么情況下執(zhí)行GC以及執(zhí)行GC的方式;4,如何監(jiān)控和優(yōu)化GC機制。
了解 Java 內(nèi)存區(qū)域劃分,是學(xué)習(xí) GC 概念的前提。解鈴還需系鈴人,相信完整學(xué)習(xí)完了底層的垃圾回收機制,讀者也將對 java 世界中對象創(chuàng)建與運行的原理有個清晰的認識吧:-)
參考文檔《深入理解Java虛擬機:JVM高級特效與最佳實現(xiàn)》,第2-3章——周志明著
Java系列筆記 - Java 內(nèi)存區(qū)域和GC機制——明舞
深入理解JVM結(jié)構(gòu)——java團長
聯(lián)系作者zhihu.com
segmentfault.com
oschina.net
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/67204.html
摘要:虛擬機所處的區(qū)域,則表示它是屬于新生代收集器還是老年代收集器。虛擬機總共運行了分鐘,其中垃圾收集花掉分鐘,那么吞吐量就是。收集器線程所占用的數(shù)量為。 本文主要從GC(垃圾回收)的角度試著對jvm中的內(nèi)存分配策略與相應(yīng)的垃圾收集器做一個介紹。 注:還是老規(guī)矩,本著能畫圖就不BB原則,盡量將各知識點通過思維導(dǎo)圖或者其他模型圖的方式進行說明。文字僅記錄額外的思考與心得,以及其他特殊情況 內(nèi)存...
摘要:看來還是功力不夠,索性拆成了六篇文章,分別從自動內(nèi)存管理機制類文件結(jié)構(gòu)類加載機制字節(jié)碼執(zhí)行引擎程序編譯與代碼優(yōu)化高效并發(fā)六個方面來做更加細致的介紹。本文先說說虛擬機的自動內(nèi)存管理機制。在類加載檢查通過后,虛擬機將為新生對象分配內(nèi)存。 歡迎關(guān)注微信公眾號:BaronTalk,獲取更多精彩好文! 書籍真的是常讀常新,古人說「書讀百遍其義自見」還是蠻有道理的。周志明老師的這本《深入理解 Ja...
摘要:運行時數(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/...
摘要:深入理解虛擬機高級特性與最佳實踐第二版讀書筆記與常見面試題總結(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...
摘要:上一篇文章講解了虛擬機中的內(nèi)存布局,這里就稍作拓展,聊聊對象在虛擬機中的一些存儲細節(jié)吧。參考文檔深入理解虛擬機高級特效與最佳實現(xiàn),第章周志明著系列筆記內(nèi)存區(qū)域和機制明舞深入理解結(jié)構(gòu)團長聯(lián)系作者 上一篇文章講解了 java 虛擬機中的內(nèi)存布局,這里就稍作拓展,聊聊 java 對象在虛擬機中的一些存儲細節(jié)吧。 本文主要圍繞虛擬機中對象如何創(chuàng)建?對象內(nèi)存都放些什么?如何訪問對象內(nèi)存?這么三...
閱讀 1382·2021-09-22 10:02
閱讀 1862·2021-09-08 09:35
閱讀 4044·2021-08-12 13:29
閱讀 2594·2019-08-30 15:55
閱讀 2257·2019-08-30 15:53
閱讀 2295·2019-08-29 17:13
閱讀 2753·2019-08-29 16:31
閱讀 2948·2019-08-29 12:24