如圖:

包含五部分:堆,方法區(qū),虛擬機棧,本地方法棧,程序計數(shù)器。
堆
堆是jvm所管理的內(nèi)存中最大的一塊內(nèi)存區(qū)域,線程共享的內(nèi)存區(qū)域,可以不使用連續(xù)的內(nèi)存地址,該區(qū)域主要存放對象實例及數(shù)組。
方法區(qū)
主要用于存儲虛擬機加載的類信息,常量,靜態(tài)變量,即時編譯器編譯后的代碼等數(shù)據(jù),可以不使用連續(xù)的內(nèi)存地址,線程共享的內(nèi)存區(qū)域。常量池是方法區(qū)的一部分。
虛擬機棧
線程私有,生命周期與線程相同,使用連續(xù)的內(nèi)存空間,描述的是java方法執(zhí)行的內(nèi)存模型:每個方法被調(diào)用時都會創(chuàng)建一個對應的棧幀,方法的執(zhí)行過程意味著對應的棧幀在虛擬機棧中入棧到出棧的過程。棧幀用于存儲局部變量表、操作數(shù)棧、動態(tài)鏈接、方法出口等信息,棧幀由三部分組成:局部變量區(qū),操作數(shù)棧,動態(tài)鏈接,方法返回地址;
局部變量表:用于存儲方法參數(shù)和方法內(nèi)定義的局部變量,通過索引來訪問;如果是非靜態(tài)方法,則在index[0]位置上存儲的是方法所屬對象的實例引用,隨后存儲的是參數(shù)和局部變量。
操作數(shù)棧:是一個后入先出棧(LIFO),通過標準的棧操作—壓棧和出棧—來訪問的,操作數(shù)棧的每一個元素可以是任意Java數(shù)據(jù)類型。在方法執(zhí)行過程中會有各種指令往棧中寫入和提取信息。JVM的執(zhí)行引擎就是基于棧的執(zhí)行引擎,其中的棧指的就是操作數(shù)棧。
當執(zhí)行一個方法時,隨著方法和字節(jié)碼指令的執(zhí)行,會從局部變量表或?qū)ο髮嵗淖侄沃袕椭瞥A炕蜃兞繉懭氲讲僮鲾?shù)棧,計算完畢將結(jié)果出棧到局部變量表或返回給方法調(diào)用者,也就是出棧/入棧操作。i++ 和 ++i 區(qū)別
i++: 從局部變量表中取出 i 壓入操作數(shù)棧,然后對局部變量表中的 i 自增1,將操作數(shù)棧棧頂值取出使用,所以線程從操作數(shù)棧讀取到的是自增之前的值。(先放入操作數(shù)棧,再自增)
++i: 先對局部變量表的 i 自增1,然后取出并壓入操作數(shù)棧,再將操作數(shù)棧棧頂值取出使用,所以,線程從操作數(shù)棧讀取到的值是自增之后的值。 (先自增,再放入操作數(shù)棧)動態(tài)鏈接:每個棧幀中包含一個在常量池中對當前方法的引用,目的是支持方法調(diào)用過程中的動態(tài)連接。
方法返回地址:方法的執(zhí)行有兩種情況退出:1.正常退出,2.異常退出;無論何種情況退出都將返回到方法被調(diào)用的位置。
本地方法棧
與虛擬機?;绢愃疲瑓^(qū)別在于虛擬機棧為虛擬機執(zhí)行的java方法服務,而本地方法棧則是為Native方法服務。
程序計數(shù)器
最小的一塊內(nèi)存區(qū)域,是一個記錄著當前線程所執(zhí)行的字節(jié)碼的行號指示器。是唯一一個在java虛擬機規(guī)范中沒有規(guī)定任何OutOfMemoryError的區(qū)域。
Java內(nèi)存模型中的有序性可以總結(jié)為:如果在本線程內(nèi)觀察,所有操作都是有序的;如果在一個線程中觀察另一個線程,所有操作都是無序的。