摘要:是描述方法執(zhí)行的內(nèi)存模型每個方法執(zhí)行的時候會同時創(chuàng)建一個棧幀,用于存儲局部變量表操作數(shù)棧動態(tài)連接返回地址方法出口等信息。虛擬機(jī)是使用局部變量表完成參數(shù)值到參數(shù)變量表的傳遞過程。堆內(nèi)存管理最大的一塊。
1. 虛擬機(jī)棧 VM Stack
線程私有,生命周期與線程相同。VM Stack是描述Java方法執(zhí)行的內(nèi)存模型:每個方法執(zhí)行的時候會同時創(chuàng)建一個棧幀(Stack Frame),用于存儲局部變量表、操作數(shù)棧、動態(tài)連接、返回地址、方法出口等信息。
局部變量表:用于存放方法參數(shù)和方法內(nèi)部定義的局部變量。虛擬機(jī)是使用局部變量表完成參數(shù)值到參數(shù)變量表的傳遞過程。
操作數(shù)棧:虛擬機(jī)把操作數(shù)棧作為它的工作區(qū)。(類似于寄存器,用于存儲指令操作需要的數(shù)據(jù)。)
動態(tài)連接:『符號引用』是每個方法的『間接引用』,『符號引用』指向方法的內(nèi)存位置,調(diào)用方法前需要把『符號引用』轉(zhuǎn)換為『直接引用』。
如果在類加載階段或者第一次調(diào)用時,把『符號引用』轉(zhuǎn)為『直接引用』,稱為『靜態(tài)解析』。
如果在運(yùn)行期間轉(zhuǎn)為『直接引用』,稱為『動態(tài)連接』。
返回地址:退出方法時要返回的位置。
棧的異常StackOverflowError:如果線程請求的棧深度大于虛擬機(jī)所允許的深度,將拋出StackOverFlowError。如無限遞歸調(diào)用當(dāng)前方法。
OutOfMemoryError:如果VM Stack可以動態(tài)擴(kuò)展,當(dāng)擴(kuò)展時無法申請到足夠的內(nèi)存時,將拋出OutOfMemoryError。
2. 本地方法棧 Native Method Stack跟VM Stack很像,但是VM Stack為執(zhí)行Java方法服務(wù),Native Method Stack為執(zhí)行Native方法服務(wù)。在Sun HotSpot虛擬中,把VM Stack和Native Method Stack合二為一。
3. 堆 HeapJVM內(nèi)存管理最大的一塊。被Java線程共享的內(nèi)存區(qū)域。
唯一功能就是存放對象實(shí)例。
堆是垃圾回收器管理的主要區(qū)域。,也被稱為『GC堆』。
根據(jù)垃圾回收分代收集算法,Heap分為新生代和老年代。
新生代:程序創(chuàng)建新對象都從新生代分配內(nèi)存。新生代分為Eden Space和Survivor Space(進(jìn)入老年代的中轉(zhuǎn)區(qū))。
老年代:經(jīng)歷多次新生代GC(Young GC)仍然存活的對象。
4. 方法區(qū) Method Area存放class的元數(shù)據(jù)信息:類名、字段信息、方法信息等 。另外還有類的常量集合:包括實(shí)際的常量和對類型、域和方法的符號引用。
簡言之,方法區(qū)=class信息+運(yùn)行時常量池。
經(jīng)常被稱為永久代。
方法區(qū)的特點(diǎn):
線程安全。由于所有線程都共享方法區(qū),必須是線程安全的(同步的)。
大小不固定,也不是連續(xù)的,可以在Heap中分配。
可以被GC,當(dāng)某個類不再使用時,JVM將卸載這個類,并進(jìn)行GC。
可以通過-XX:PermSize 和 -XX:MaxPermSize 參數(shù)限制方法區(qū)的大小。
5. 程序計(jì)數(shù)器程序計(jì)數(shù)器是一塊較小的內(nèi)存空間,可以看作是當(dāng)前線程所執(zhí)行的字節(jié)碼的行號指示器。分支、循環(huán)、跳轉(zhuǎn)、異常處理、線程恢復(fù)等基礎(chǔ)功能都需要依賴這個計(jì)數(shù)器來完成。
此內(nèi)存區(qū)域是唯一一個在Java 虛擬機(jī)規(guī)范中沒有規(guī)定任何OutOfMemoryError情況的區(qū)域。
JVM 會試圖為相關(guān)Java對象在Eden Space中初始化一塊內(nèi)存區(qū)域。
當(dāng)Eden空間足夠時,內(nèi)存申請結(jié)束;否則到下一步。
JVM 試圖釋放在Eden中所有不活躍的對象(這屬于1或更高級的垃圾回收)。釋放后若Eden空間仍然不足以放入新對象,則試圖將部分Eden中活躍對象放入Survivor區(qū)。
Survivor區(qū)被用來作為Eden及Old的中間交換區(qū)域,當(dāng)Old區(qū)空間足夠時,Survivor區(qū)的對象會被移到Old區(qū),否則會被保留在Survivor區(qū)。
當(dāng)Old區(qū)空間不夠時,JVM 會在Old區(qū)進(jìn)行完全的垃圾收集(0級)。
完全垃圾收集后,若Survivor及Old區(qū)仍然無法存放從Eden復(fù)制過來的部分對象,導(dǎo)致JVM無法在Eden區(qū)為新對象創(chuàng)建內(nèi)存區(qū)域,則出現(xiàn)“outofmemory”錯誤。
對象內(nèi)存訪問即使是最簡單的訪問,也會卻涉及Java 棧、Java 堆、方法區(qū)這三個最重要內(nèi)存區(qū)域之間的關(guān)聯(lián)關(guān)系,如下面的這句代碼:
Object obj = newObject();
VM Stack:“Object obj”這部分的語義將會反映到VM Stack的本地變量表中,作為一個reference 類型數(shù)據(jù)出現(xiàn)。
Heap:而“new Object()”這部分的語義將會反映到Java 堆中,形成一塊存儲了Object 類型所有實(shí)例數(shù)據(jù)值(Instance Data,對象中各個實(shí)例字段的數(shù)據(jù))的結(jié)構(gòu)化內(nèi)存,根據(jù)具體類型以及虛擬機(jī)實(shí)現(xiàn)的對象內(nèi)存布局(Object Memory Layout)的不同,這塊內(nèi)存的長度是不固定的。
方法區(qū):另外,在Java 堆中還必須包含能查找到此對象類型數(shù)據(jù)(如對象類型、父類、實(shí)現(xiàn)的接口、方法等)的地址信息,這些類型數(shù)據(jù)則存儲在方法區(qū)中。
原文地址:http://blog.csdn.net/u0121526...
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/66893.html
摘要:作為一個程序員,不了解內(nèi)存模型就不能寫出能夠充分利用內(nèi)存的代碼。程序計(jì)數(shù)器是在電腦處理器中的一個寄存器,用來指示電腦下一步要運(yùn)行的指令序列。在虛擬機(jī)中,本地方法棧和虛擬機(jī)棧是共用同一塊內(nèi)存的,不做具體區(qū)分。 作為一個 Java 程序員,不了解 Java 內(nèi)存模型就不能寫出能夠充分利用內(nèi)存的代碼。本文通過對 Java 內(nèi)存模型的介紹,讓讀者能夠了解 Java 的內(nèi)存的分配情況,適合 Ja...
摘要:內(nèi)存模型和運(yùn)行時數(shù)據(jù)區(qū)域的關(guān)系主內(nèi)存對應(yīng)著堆,工作內(nèi)存對應(yīng)著棧。在的單例模式中有運(yùn)用到二運(yùn)行時數(shù)據(jù)區(qū)域內(nèi)存區(qū)域因?yàn)榈倪\(yùn)行時數(shù)據(jù)區(qū)域一直在改善,所以不同版本之間會有不同。 一、java內(nèi)存模型 showImg(https://segmentfault.com/img/remote/1460000016694250?w=1810&h=941); java定義內(nèi)存模型的目的是:為了屏蔽各種...
摘要:內(nèi)存模型首先介紹下程序具體執(zhí)行的過程源代碼文件后綴會被編譯器編譯為字節(jié)碼文件后綴由中的類加載器加載各個類的字節(jié)碼文件,加載完畢之后,交由執(zhí)行引擎執(zhí)行在整個程序執(zhí)行過程中,會用一段空間來存儲程序執(zhí)行期間需要用到的數(shù)據(jù)和相關(guān)信息,這段空間一般被 [TOC] JVM內(nèi)存模型 首先介紹下Java程序具體執(zhí)行的過程: Java源代碼文件(.java后綴)會被Java編譯器編譯為字節(jié)碼文件(....
摘要:的內(nèi)存模型概述虛擬機(jī)在執(zhí)行程序的過程中,會把它所管理的內(nèi)存劃分為若干個不同的數(shù)據(jù)區(qū)域。程序計(jì)數(shù)器這是一塊較小的內(nèi)存,它可以看做是當(dāng)前線程所執(zhí)行的字節(jié)碼的行號指示器。 JVM的內(nèi)存模型 概述 Java虛擬機(jī)在執(zhí)行java程序的過程中,會把它所管理的內(nèi)存劃分為若干個不同的數(shù)據(jù)區(qū)域。這些區(qū)域都有各自的用途,以及創(chuàng)建和銷毀的時間,有的區(qū)域隨著虛擬機(jī)進(jìn)程的啟動而存在,有些區(qū)域則依賴用戶線程的啟動...
摘要:在之前,它是一個備受爭議的關(guān)鍵字,因?yàn)樵诔绦蛑惺褂盟占骼斫夂驮矸治龊喎Q,是后提供的面向大內(nèi)存區(qū)數(shù)到數(shù)多核系統(tǒng)的收集器,能夠?qū)崿F(xiàn)軟停頓目標(biāo)收集并且具有高吞吐量具有更可預(yù)測的停頓時間。 35 個 Java 代碼性能優(yōu)化總結(jié) 優(yōu)化代碼可以減小代碼的體積,提高代碼運(yùn)行的效率。 從 JVM 內(nèi)存模型談線程安全 小白哥帶你打通任督二脈 Java使用讀寫鎖替代同步鎖 應(yīng)用情景 前一陣有個做...
閱讀 1523·2023-04-26 02:03
閱讀 4707·2021-11-22 13:53
閱讀 4580·2021-09-09 11:40
閱讀 3782·2021-09-09 09:34
閱讀 2125·2019-08-30 13:18
閱讀 3501·2019-08-30 11:25
閱讀 3295·2019-08-26 14:06
閱讀 2545·2019-08-26 13:52