Java基礎--Java記憶體管理與記憶體回收,--java記憶體回收
Java自動記憶體管理
在講解記憶體管理之前,首先需要瞭解對象和對象引用的區別
對象是類的一個執行個體,以人這個類為例,Person是我們定義的一個類
public class Person{}
public Person person;
person = new Person();
而new Person()是建立了一個對象,person是對這個對象的引用,它可以指向任意一個對象。
1.1 java運行時地區(什麼地方存什麼)
程式計數器:可以理解為線程當前執行位置的標記,用途:線程切換。
棧
>虛擬機器棧:每一個方法執行時建立一個棧幀,方法的執行代表著棧幀在在記憶體區換入換出。這裡面儲存著方法參數和局部變數,類型為基礎資料型別 (Elementary Data Type)、數組/對 象的引用。
>本地方法棧:作用和VM stacks類似,只不過服務於native方法。圖片引自參考2.
堆:存放對象執行個體。記憶體回收主要指標對堆的回收策略。
方法區:類資訊,常量,靜態變數(static 、class),包含常量池
1.2 記憶體回收機制
記憶體回收(Garbage Collection,GC)自動清空堆中不再使用的對象。
如果一個對象沒有引用,我們稱這個對象不可達,記憶體回收用於釋放不可達的對象所佔據的記憶體,這是記憶體回收的基本原則。
記憶體回收分為兩個步驟:判斷這個對象是否已死(不可達)和清除這個對象。
1.2.1 對象已死嗎
> 引用計數。給對象添加一個計數引用器,當為0時,判斷對象不可達。缺點:無法解決相互引用的情況。ObjA.instance= ObjB;ObjB.instance = ObjA; ObjA和ObjB已經不能訪問,但引用計數法無法通知記憶體回收機制。
改進:以棧和static資料為根(root),從根出發,跟隨所有的引用,就可以找到所有的可到達對象。也就是說,一個可到達對象,一定被根引用,或者被其他可 到達對象引用。如:引自參考2
1.2.2. 記憶體回收策略
-
- 標記-清除(mark-sweep)演算法:標記誰不可達,然後刪除.
缺點:a.效率,兩個步驟效率都不高;b,導致產生大量的空間片段
-
- 複製-清除:將記憶體劃等分為兩塊地區A和B,掃描A,將可達的對象複製到B中,然後將A清空。缺點:代價太大
改進:由於對象絕大部分生命週期較短,將記憶體按照一定比例(通常8:1:1)劃分為A,B,C,將A和B可達的Object Storage Service到C中,將A和B 清空,A和C作為上一步驟 的A和B。
參考:1,http://jingyan.baidu.com/article/a501d80cf734c3ec630f5e25.html
2,http://www.cnblogs.com/vamei/archive/2013/04/28/3048353.html重點推薦
3,《深入理解Java虛擬機器:JVM進階特性與最佳實務》.pdf