Java記憶體管理機制
記憶體劃分割槽域
方法區(Method Area), 虛擬機器棧(VM Stack), 本地方法棧(Native Method Stack), 堆(Heap), 程式計數器(Program Counter Register)
1. 程式計數器(Program Counter Register)
執行緒私有的.當前執行緒所執行的位元組碼的行號指示器.通過改變這個計數器的值來選取下一條需要執行的位元組碼指令.
2. 虛擬機器棧(VM Stack)
執行緒私有的,生命週期與執行緒相同.每個方法被執行的時候都會建立一個棧幀(Stack Frame)用於儲存區域性變數,操作棧,動態連結,方法出口等資訊.每一個方法被呼叫直至執行完成的過程,對應著一個棧幀在虛擬機器棧中從入棧到出棧的過程.
3. 本地方法棧(Native Method Stacks)
與虛擬機器棧發揮的作用非常相似.區別是虛擬機器棧執行Java方法(也就是位元組碼)服務,而本地方法棧則是為虛擬機器使用到的Native方法服務.
4. 堆(Heap)
最大的一塊,所有執行緒共享的一塊記憶體,虛擬機器啟動時建立.唯一目的就是存放物件例項.垃圾收集器管理的主要區域,很多時候也被稱作"GC堆"(Garbage Collected Heap)
5. 方法區(Method Area)
各個執行緒共享區域,儲存已被虛擬機器載入的類資訊,常量,靜態變數,即時編譯器編譯後的程式碼等資料.執行時常量池(Runtime Constant Pool)是方法區的一部分,存放編譯期生成的各種字面量和符號引用
物件訪問
Object obj = new Object();
Object obj將會反映到Java棧的本地變數表中,作為一個reference型別資料出現.而”new Object()”這部分則會反映到Java堆中,形成了一塊儲存了Object型別所有例項資料的結構化記憶體.而reference型別訪問物件的方式有兩種:
- 使用控制程式碼,Java堆中將會劃分出一塊記憶體作為控制程式碼池,reference儲存控制程式碼地址
- 使用指標,reference中直接儲存的就是物件地址.主要虛擬機器(Sun HotSpot)使用的這一種
垃圾回收(GC)
物件已死
- 引用計數法(Reference Counting)
引用時,計數器加1,失效時減1.簡單高效,但是無法解決相互迴圈引用的問題. - 根搜尋演算法(GC Roots Tracing)
主流的方法.通過一系列名為”GC Roots”的物件作為起始點,從這些節點開始向下搜尋,搜尋所走過的路徑稱為引用鏈(Reference Chain),當一個物件沒有任何引用鏈相連時,則證明物件是不可用的.可作為GC Roots的物件有以下幾種:
- 虛擬機器棧(棧幀中的本地變數表)中的引用的物件
- 方法區中的類靜態屬性引用的物件
- 方法區中的常量引用的物件
- 本地方法棧中JNI的引用的物件(類似於第一種)
何時回收
一個物件死亡,至少要經歷兩次標記過程:第一次判斷是否有與GC Roots相連線的引用鏈,如果沒有被執行過finalize指令,則會執行,被放置在一個F-Queue中,由虛擬機器建立的Finalizer執行緒執行.GC將對F-Queue中的物件進行得二次小規模標記.
回收方法區
方法區(或者HotSpot虛擬機器中的永久代)的回收的"價效比"一般比較低.主要回收廢棄常量和無用的類
垃圾收集演算法
標記-清除(Mark-Sweep)演算法
分為標記,清除兩個階段.首先標記出所有需要回收的物件,在標記完成後統一回收所有被標記的物件.
有兩個缺點:(1)效率 (2)空間,容易造成碎片複製(Copying)演算法
將可用記憶體按照容量劃分為大小相等的兩塊,每次只使用其中的一塊,當這一塊的記憶體用完了,就將存活著的物件複製到另一塊上面,然後再把已使用過的記憶體空間一次清理掉.這樣實現簡單,但是代價是記憶體縮小到原來的一般,空間代價較高.
- 標記-整理演算法
複製收集演算法在物件存活率較高的時候就要執行較多的複製操作,效率變低,而且空間浪費高.標記整理演算法是讓所有的存活物件都向一端移動,然後直接清理掉端邊界外的記憶體.
- 分代收集演算法
根據物件的存貨週期劃分為幾塊.一般把堆分為新生代(Young Generation)和老年代(Old Generation).根據各個年代的特點採用最適當的收集演算法.在新生代如果有大批物件死去,少量存活,就採用複製演算法,只需要少量的複製就可以完成收集.而老年代中則採取"標記-清理"或者"標記-整理"演算法來回收
垃圾收集器
垃圾收集演算法的具體實現
物件分配回收策略
- 物件優先在新生代Eden分配.當Eden區沒有足夠的空間進行分配時,虛擬機器將發起一次Minor GC.(新生代GC為MinorGC; 老年代GC為Major GC/Full GC)
- 大物件直接進入老年代.避免在Eden區以及兩個Survivor區之間發生大量的記憶體拷貝.
- 長期存活的物件進入老年區.給每個物件定義一個物件年齡(Age)計數器,年齡增加到一定程度時(預設為15歲),就晉升到老年代
- 動態物件年齡判定.如果Survivor空間中相同年齡所有物件大小的總和大於Survivor空間的一半,年齡大於或等於該年齡的物件就可以直接進入老年代.
- 空間分配擔保.如果晉升到老年代的平均大小大於老年代的剩餘空間大小,則改為直接進行一次Full GC.
相關文章
- 淺析java記憶體管理機制Java記憶體
- Java的記憶體管理機制之記憶體區域劃分Java記憶體
- javaScript 記憶體管理機制JavaScript記憶體
- Qt 記憶體管理機制QT記憶體
- jvm記憶體管理機制JVM記憶體
- Qt 記憶體管理機制薦QT記憶體
- linux記憶體管理機制Linux記憶體
- Java的記憶體回收機制Java記憶體
- 記憶體管理機制的發展記憶體
- ARC記憶體管理機制詳解記憶體
- 【記憶體管理】頁面分配機制記憶體
- Java程式執行記憶體機制Java記憶體
- java基礎:記憶體分配機制Java記憶體
- 圖解Java記憶體回收機制圖解Java記憶體
- 什麼是記憶體管理?其最主要作用?OC記憶體管理機制?記憶體
- java基礎(一):談談java記憶體管理與垃圾回收機制Java記憶體
- JVM自動記憶體管理機制 二JVM記憶體
- 淺談Linux記憶體管理機制Linux記憶體
- AIX虛擬記憶體管理機制(轉)AI記憶體
- IBM的AIX記憶體管理機制IBMAI記憶體
- 深入理解Java虛擬機器(自動記憶體管理機制)Java虛擬機記憶體
- Python如何管理記憶體?記憶體分配機制是什麼?Python記憶體
- 深入理解Java虛擬機器筆記-自動記憶體管理機制Java虛擬機筆記記憶體
- 建立快取記憶體機制-java版快取記憶體Java
- Java記憶體模型,垃圾回收機制,常用記憶體命令及工具Java記憶體模型
- 深入理解java虛擬機器 筆記一 ---自動記憶體管理機制Java虛擬機筆記記憶體
- JavaScript 記憶體機制JavaScript記憶體
- 一文洞悉JVM記憶體管理機制JVM記憶體
- Python記憶體管理機制-《原始碼解析》Python記憶體原始碼
- Objective-C中的記憶體管理機制Object記憶體
- 深度學習 Caffe 記憶體管理機制理解深度學習記憶體
- javascript的垃圾回收機制和記憶體管理JavaScript記憶體
- android記憶體管理機制與優化Android記憶體優化
- 淺談Linux的記憶體管理機制Linux記憶體
- 【江楓】AIX虛擬記憶體管理機制AI記憶體
- Java的記憶體 -JVM 記憶體管理Java記憶體JVM
- 你必須瞭解的java記憶體管理機制(四)-垃圾回收Java記憶體
- JVM深入淺出 -- Java記憶體分配機制JVMJava記憶體