Java自動內存管理
在講解內存管理之前,首先需要了解對象和對象引用的區別
對象是類的一個實例,以人這個類為例,Person是我們定義的一個類
public class Person{}
public Person person;
person = new Person();
而new Person()是新建了一個對象,person是對這個對象的引用,它可以指向任意一個對象。
1.1 java運行時區域(什麼地方存什麼)
程序計數器:可以理解為線程當前執行位置的標記,用途:線程切換。
棧
>虛擬機棧:每一個方法執行時創建一個棧幀,方法的執行代表著棧幀在在內存區換入換出。這裡面存儲著方法參數和局部變量,類型為基本數據類型、數組/對 象的引用。
>本地方法棧:作用和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. 垃圾回收策略
缺點:a.效率,兩個步驟效率都不高;b,導致產生大量的空間碎片
改進:由於對象絕大部分生命周期較短,將內存按照一定比例(通常8:1:1)劃分為A,B,C,將A和B可達的對象存儲到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