1. 程式人生 > >JVM記憶體空間組成+GC回收機制

JVM記憶體空間組成+GC回收機制

JVM

1. 程式計數器
一塊較小的執行緒私有空間, 可以當作當前執行緒所執行位元組碼的行號顯示器, 通過改變計數器的值選擇執行的位元組碼.
2. 虛擬機器棧
一塊執行緒私有的記憶體空間, 每起一個執行緒就會起一個執行緒棧, 而在一個執行緒中可以呼叫多個方法, ,每起一個方法就會起一個棧幀, 所以一個執行緒棧中有多個棧幀. 每一個方法從呼叫到執行完成的過程, 就代表一個棧幀在虛擬機器棧中入棧到出棧的過程. 每一個棧幀存放著區域性變數, 操作函式等資訊. 當執行緒請求的棧的深度大於當前虛擬機器棧的深度時, 就會觸發StackOverFlowError.
3. 本地方法棧
Java訪問C語言等其他語言所用到的棧, 原理上與虛擬機器棧類似
4. 堆


最大JVM記憶體, 執行緒共享, 只能儲存物件.
5. 方法區
執行緒共享的記憶體區. 用於儲存已經被載入的類資訊, 常量,靜態變數等
6. 執行時常量
方法區的一部分, 類檔案中有一項資訊時常量池, 用來儲存編譯器生成的字面量和符號引用.
7. 直接記憶體
不是Java虛擬機器中定義的記憶體區域

GC

1. 確定垃圾
a. 引用基數演算法
給物件中新增一個引用計數器, 每當由一個地方引用它的時候, 計數器就+1; 當引用失效時, 計數器就-1, 計數器為0的物件不被使用.
但是這個演算法無法解決物件之間的相互引用關係
b. 正向可達演算法
得到堆記憶體中一定不是垃圾的根的物件,GCRoots, 順著GCRoots引用往下找, 能順藤摸瓜找到的就是好瓜,否則就是垃圾
2. 垃圾回收演算法


a. 標記清除: 兩個階段: 1. 標記階段, 通過正向可達演算法 2.清除階段
缺點: 記憶體不連續, 碎片化
b. 複製演算法:一般在新生代中使用
將原有記憶體空間啊分為兩塊, 每次使用一塊, 垃圾回收時將正在使用的記憶體塊中存活物件複製到未使用的那一塊記憶體中, 之後清除正在使用的記憶體快中所有空間
c. 標記-壓縮演算法: 一般用在老年代
通過正向可達演算法, 將所有存活的物件壓縮到記憶體空間的一端, 之後清理邊界外的所有空間
d. 分代演算法 : JVM使用
將記憶體分為新生代和老生代
新生代由於存活物件不多, 使用複製演算法
老生代存活率高, 使用標記-壓縮演算法