Java Garbage Collection筆記
-
Java
Monday, October 22, 2007
這是前陣子對公司內部分享gc觀念的筆記,放上來留個紀錄。
JVM使用的記憶體
Java Heap
1. Java 程式執行時,JVM 用來配置Java objects 的記憶體
2. GC 發生作用的記憶體
3. 預設值 (僅供參考)
*Xms大約都是4MB
*Xmx
1.AIX 為64MB
2.Windows 為實體記憶體的二分之一(16MB ~ 2GB -1)
3.Linux 為實體記憶體的二分之一(16MB ~ 512MB -1)
Native Heap
1. JVM 用來它內部運作的記憶體
2. JNI: Third party 的native module
3. 大小取決於產生的程式碼、產生的thread、GC 時用於保存javaobject 資訊
與產生或最佳化程式碼時的暫存空間
4. 預設值 (僅供參考) *128K(會隨著需求往上增長)
GC三部曲
1. Mark Phase
* 搜尋Java Heap 內全部的物件,找出已經沒有在使用中的物件
2. Sweep Phase
* 將無用的物件清除
3. Compaction Phase(optional)
*搬動物件,壓實Java Heap ,藉以移除物件之間的空白空間
*有些物件是無法搬動 Pinned (pointer 來自JNI, thread) , Dosed (pointer 來自stack)
GC的天時地利
* 當物件實體(Instance)沒有被參考時, 才允許被回收
* 參閱圖1範例判斷物件A~E,變成允許回收的順序 (A→B 為B被A所參考)* 範例程式碼
1: public void method1(){
2: Myclass a = new Myclass();
3: a = null; //步驟2產生的物件可以被gc
4: java.util.Date d = new java.util.Date();
5: d = new java.util.Date( long_date ); //步驟4產生的物件可以被gc
6: } //步驟5產生的物件可以被gc
*下面程式碼中A B C變成允許回收的順序?class OBJ{
private static A a = new A();
public B b = new B();
public void method1(){
C c = new C();
}
}
* 只能建議GC時機,但實際執行由JVM決定. 建議JVM執行GC方式如下
1. System.gc()
2. Runtime.getRuntime().gc()
* finalize()
1. finalize方法位於Java.Object
2. 當物件被JVM回收時會呼叫
3. 一般可用來手動釋放資源
練習
*Case 1 請問步驟8時,步驟1和2產生的物件是否允許被回收?
1: A a = new A;
2: A b = new A;
3: A c=b;
4: b=a;
5: a=null;
6: a=c;
7: b=null;
8: c=null;
9: ......
*Case 2 請問步驟4所產生的object何時允許被回收?
1. public class Test {
2. private Demo d;
3. void start() {
4. d = new Demo();
5. this.takeDemo(d) ;
6. }
7.
8. void takeDemo(Demo demo) {
9. demo = null;
10. demo = new Demo();
11. }
12. public static void main(String[] arg){
13. Test test = new Test();
14. test.start();
15. test.start();
16. }
17.}
* Case 3 下列程式碼為圖1的實作,執行結果為何?
import java.util.ArrayList;
public class TestOBJ {
private String name;
private ArrayList
referenceList = new ArrayList();
public TestOBJ(String name){
this.name = name;
}
public String getName(){
return name;
}
public void reference(TestOBJ obj){
referenceList.add(obj);
System.out.println(name + " -> "+obj.getName());
}
protected void finalize() throws Throwable {
System.out.println(name + " got gc.");
super.finalize();
}
public static void main(String[] arg){
TestOBJ a = new TestOBJ("A");
TestOBJ b = new TestOBJ("B");
TestOBJ c = new TestOBJ("C");
TestOBJ d = new TestOBJ("D");
TestOBJ e = new TestOBJ("E");
TestOBJ f = new TestOBJ("F");
a.reference(b);
b.reference(c);
b.reference(d);
d.reference(e);
d.reference(f);
f.reference(c);
c.reference(e);
System.out.println("==========="); //分隔線
a = null;
b = null;
c = null;
d = null;
e = null;
f = null;
System.gc(); //假設jvm執行gc
}
}


