天天看點

jvm運作記憶體配置設定

引用   http://www.cnblogs.com/hewenwu/p/3662529.html

一、 基本概念

   每運作一個java程式會産生一個java程序,每個java程序可能包含一個或者多個線程,每一個Java程序對應唯一一個JVM執行個體,每一個JVM執行個體唯一對應一個堆,每一個線程有一個自己私有的棧。程序所建立的所有類的執行個體(也就是對象)或數組(指的是數組的本身,不是引用)都放在堆中,并由該程序所有的線程共享。Java中配置設定堆記憶體是自動初始化的,即為一個對象配置設定記憶體的時候,會初始化這個對象中變量。雖然Java中所有對象的存儲空間都是在堆中配置設定的,但是這個對象的引用卻是在棧中配置設定,也就是說在建立一個對象時在堆和棧中都配置設定記憶體,在堆中配置設定的記憶體實際存放這個被建立的對象的本身,而在棧中配置設定的記憶體隻是存放指向這個堆對象的引用而已。局部變量 new 出來時,在棧空間和堆空間中配置設定空間,當局部變量生命周期結束後,棧空間立刻被回收,堆空間區域等待GC回收。

具體的概念:JVM的記憶體可分為3個區:堆(heap)、棧(stack)和方法區(method,也叫靜态區):

堆區: 

1.存儲的全部是對象,每個對象都包含一個與之對應的class的資訊(class的目的是得到操作指令) ;

2.jvm隻有一個堆區(heap),且被所有線程共享,堆中不存放基本類型和對象引用,隻存放對象本身和數組本身;

棧區: 

1.每個線程包含一個棧區,棧中隻儲存基礎資料類型本身和自定義對象的引用;

2.每個棧中的資料(原始類型和對象引用)都是私有的,其他棧不能通路;

3.棧分為3個部分:基本類型變量區、執行環境上下文、操作指令區(存放操作指令);

方法區(靜态區): 

1.被所有的線程共享,方法區包含所有的class(class是指類的原始代碼,要建立一個類的對象,首先要把該類的代碼加載到方法區中,并且初始化)和static變量。 

2.方法區中包含的都是在整個程式中永遠唯一的元素,如class,static變量。 

線程間通信必須要經過主記憶體。

Java記憶體模型定義了以下八種操作來完成:

lock(鎖定):作用于主記憶體的變量,把一個變量辨別為一條線程獨占狀态。

unlock(解鎖):作用于主記憶體變量,把一個處于鎖定狀态的變量釋放出來,釋放後的變量才可以被其他線程鎖定。

read(讀取):作用于主記憶體變量,把一個變量值從主記憶體傳輸到線程的工作記憶體中,以便随後的load動作使用

load(載入):作用于工作記憶體的變量,它把read操作從主記憶體中得到的變量值放入工作記憶體的變量副本中。

use(使用):作用于工作記憶體的變量,把工作記憶體中的一個變量值傳遞給執行引擎,每當虛拟機遇到一個需要使用變量的值的位元組碼指令時将會執行這個操作。

assign(指派):作用于工作記憶體的變量,它把一個從執行引擎接收到的值指派給工作記憶體的變量,每當虛拟機遇到一個給變量指派的位元組碼指令時執行這個操作。

store(存儲):作用于工作記憶體的變量,把工作記憶體中的一個變量的值傳送到主記憶體中,以便随後的write的操作。

write(寫入):作用于主記憶體的變量,它把store操作從工作記憶體中一個變量的值傳送到主記憶體的變量中。

jvm運作記憶體配置設定

其關于多線程的工作要點如下:

共享變量存儲于主記憶體中,每個線程都可以通路。

每個線程都有私有的工作記憶體,或稱本地記憶體。這隻是個邏輯概念,其實質是涵蓋了寄存器、緩存、編譯器優化和硬體等。

共享變量隻以副本的形式,存儲在本地記憶體中。

線程不能直接操作主記憶體,隻有操作了本地記憶體中的副本,才能重新整理到主記憶體中。

每個線程也不能操作其它線程的私有的本地記憶體

轉載于:https://my.oschina.net/6582886lp/blog/776735