JVM內存結構:
堆:存放所有new出來的東西。GC堆是Java虛擬機所管理的內存中最大的一塊內存區域,也是被各個線程共享的內存區域。堆被分爲新生代和老年代。
方法區:存儲虛擬機加載的類信息,常量,靜態變量,各個內存共享的內存區域。默認大小爲16mb,最大值爲64mb
虛擬機棧:描述的是Java方法執行的內存模型。每一個方法被執行的時候,都會創建一個“棧幀”,用於存儲局部變量表,操作棧,方法出口等。
本地方法棧:爲Native方法服務。
程序計數器:分支、循環、跳轉、異常處理、線程恢復。
JVM啓動流程:
JVM基本結構:
GC回收機制:
判斷對象是否存活:
1.引用計數:每個對象都有一個引用計數屬性,新增一個引用時計數加1,引用釋放時減1,計數爲0的時候可回收。
2.可達性分析:從GC Roots開始向下搜索,搜索所走過的路徑稱爲引用鏈,當一個對象沒有任何引用鏈相連時,則該對象不可用,回收。
GC回收的四個算法:
1.標記-清除算法:該算法分爲兩個階段:
1>標記階段:找到所有可訪問的對象,做個標記
2>清除階段:遍歷堆,找到未被標記的對象回收
優點:
1>可以解決循環引用的問題
2>必要時纔回收
缺點:
1>回收時,應用需要掛起,也就是stop the world.
2>標記和清除的效率不高,尤其是掃描的對象比較多的時候
2.複製算法:
首先將內存分爲大小相等的兩部分(假設A、B兩部分),每次呢只使用其中的一部分(這裏我們假設爲A區),等這部分用完了,這時候就將這裏面還能活下來的對象複製到另一部分內存(這裏設爲B區)中,然後把A區中的剩下部分全部清理掉。
優點:
- 吞吐量大,只需要遍歷一次From空間Sweep需要遍歷兩次,而且只複製存活的對象。
- 高速分配,不需要通過空閒鏈表直接在連續的內存上進行分配。
- 沒有碎片。
- 與緩存兼容,複製存活對象時採用深度優先算法使相關聯的對象都在附近。
缺點:
- 堆的使用效率低,必須分配一個To,其不能分配對象。
- 不兼容保守式GC算法,需要移動對象。
- 遞歸調用,複製對象的深度優先算法是通過遞歸調用實現的,遞歸將消耗棧等資源。
3.標記-整理算法:算法不直接對可回收對象進行清理,而是讓所有可用的對象都向一端移動。然後直接清理掉邊界意外的內存。
4.分帶收集算法:
根據對象的存活週期不同將內存劃分爲新生代和老年代,存活週期短的爲新生代,存活週期長的爲老年代。這樣就可以根據每塊內存的特點採用最適當的收集算法。
新生代的中每次垃圾收集中會發現有大批對象死區,只有少量存活,那就選用複製算法,只需要付出少量存活對象的複製成本就可以完成收集。老年代中因爲對象的存活率高,沒有額外的控件對它進行分配擔保,就必須使用“標記-清掃”或者“標記-整理”算法來進行回收。