1. 程式人生 > >jvm內存模型中-棧,方法區,程序計數器是線程安全的

jvm內存模型中-棧,方法區,程序計數器是線程安全的

如同 其它 必須 lan tro 應用 之前 信息 大小

文章轉自 https://www.cnblogs.com/myna/p/7567889.html

引文

JDK7及之前版本的方法區(Method Area)和Java堆一樣,是各個線程共享的內存區域,用於存儲已經被虛擬機加載的類信息、常量、靜態常量、即時編譯器編譯後的代碼等數據。雖然Java虛擬機規範把方法區描述為堆的一個邏輯部分,但它有另外一個名字叫Non-Heap(非堆)。根據Java虛擬機規範的規定,當方法區無法滿足內存分配需求時,將拋出OutOfMemoryError異常。

細分

方法區被分為兩個主要的子區域:

  1. 持久代 這個區域會存儲包括類定義、結構、字段、方法(數據及代碼)以及常量在內的類相關數據。它可以通過-XX:PermSize及-XX:MaxPermSize來進行調節。如果它的空間用完了,會導致java.lang.OutOfMemoryError: PermGenspace的異常。而JDK8開始,持久代已經被徹底刪除了,取代它的是另一個內存區域也被稱為元空間。

  2. 存放數據

    方法區存儲的是每個class的信息: 1.類加載器引用(classLoader) 2.運行時常量池 所有常量、字段引用、方法引用、屬性 3.字段數據 每個方法的名字、類型(如類的全路徑名、類型或接口) 、修飾符(如public、abstract、final)、屬性 4.方法數據 每個方法的名字、返回類型、參數類型(按順序)、修飾符、屬性 5.方法代碼 每個方法的字節碼、操作數棧大小、局部變量大小、局部變量表、異常表和每個異常處理的開始位置、結 束位置、代碼處理在程序計數器中的偏移地址、被捕獲的異常類的常量池索引

特點

1.方法區是線程安全的。由於所有的線程都共享方法區,所以,方法區裏的數據訪問必須被設計成線程安全的。例如,假如同時有兩個線程都企圖訪問方法區中的同一個類,而這個類還沒有被裝入JVM,那麽只允許一個線程去裝載它,而其它線程必須等待。

2.方法區的大小不必是固定的,JVM可根據應用需要動態調整。同時,方法區也不一定是連續的,方法區可以在一個堆(甚至是JVM自己的堆)中自由分配。

3.方法區也可被垃圾收集,當某個類不在被使用(不可觸及)時,JVM將卸載這個類,進行垃圾收集 代碼緩存 個緩存區域是用來存儲編譯後的代碼。編譯後的代碼就是本地代碼(硬件相關的),它是由JIT(Just In Time)編譯器生成的,這個編譯器是Oracle HotSpot JVM所特有的。

jvm內存模型中-棧,方法區,程序計數器是線程安全的