JVM
JVM的內存模型
PC寄存器
記錄當前線程執行的字節碼的行號,是線程私有的。
虛擬機棧
存放的是棧幀,線程私有。
棧幀包括了局部變量表、操作數棧、動態鏈接、返回值地址。
本地方法棧
與虛擬機棧相似,它服務的是本地方法,線程私有。
堆
對象的實例、數組都存在於堆。GC回收的地方
方法區
存放已經被加載的類信息、常量、靜態變量、編譯後的代碼。回收的目標是常量池。
GC(垃圾回收)
堆的分類
新生代與老年代
新生代和老年代的內存比例爲1:2,新生代分爲三個部分,eden、survivor1和suivivor2。三者的比例是8:1:1,當new一個對象時,如果對象的非常大,就放到老年代,否則放入eden,eden中的對象在經歷一次GC後,如果還有引用指向它,那麼放入survivor1,在經歷一次放入suivivor2,往復,直到一定次數後,如果還存在,則放入老年代。
如何判斷對象可以被回收了
- 引用計數法
當指向一個對象的引用爲0時,就判斷這個對象可以被GC清楚,在一個對象被new出來的時候,在對象頭中會有一個引用計數器,當一個引用指向這個對象時+1,引用消失的時候-1. - 根搜索(正向可達)
引用計數法無法解決循環引用的問題,根搜索從一個程序啓動時會有一些根對象,從這些根對象出發,尋找哪些對象可找到,能找到的對象就不是垃圾,找不到的就可以使用GC。根對象:
垃圾回收算法
Mark-Sweep(標記清除)
根據跟搜索方法,在堆中標記可回收的對象。然後進行一次掃除,將可回收的對象清除。但是容易形成內存碎片化的現象。
Copying(拷貝)
將內存分爲兩塊,一半放數據,一般不放,先經過一次標記所有可用的對象,將他們拷貝到另一半的內存上,然後將原來的內存整體擦除。內存浪費
Mark-compact(標記-壓縮)
先標記對象,將不可回收的對象放到已經回收了的對象的位置。無內存浪費。
垃圾收集器
Serial
單線程的收集器,收集垃圾時必須stop the world,在新生代採用的是複製算法,Serial Old在老年代使用標記整理-算法。
Parallel
Parallel Scavenge在新生代採用並行的多線程收集,使用複製算法。Parallel Old 在老年代使用多線程收集,採用標記-整理算法。
CMS
G1
採用分區策略,將堆內存分爲多個區。