Garbage Collection
程序员文章站
2022-05-09 16:16:58
...
以下為Java記憶體管理的幾個要項…
1. 在Java的程式語言規格之中並未詳細說明殘餘記憶體收集機制的法則,因此每一家JVM的開發廠商都根據自己的演算法來研發殘餘記憶體收集機制。
2. 殘餘記憶體是以單獨的執行緒來執行的。
3. 通常JVM會在記憶體不足時啟動殘餘記憶體收集的執行緒。
4. 程式設計師可以透過以下兩種方法來”通知”JVM啟動殘餘記憶體收集:
當程式設計師以上述兩種方法通知JVM啟動殘餘記憶體收集時,並不能保證JVM會啟動殘餘記憶體收集,事實上JVM只是在以上方法呼叫時”儘可能”執行殘餘記憶體收集。
5. 要確保不需要的物件會被殘餘記憶體機制收集掉的話,必須移除該物件的所有參考,移除參考的方法很簡單,如下… (將物件設為null即可)
6. 當一個method執行完離開它的區間時,所有區域物件都會自動被設為null,等待被回收。如下程式,當程式離開doSomething時,會產生三個垃圾物件,等待被回收。 (三個為陣列本身及陣列的兩個元素)
7. 殘餘記憶體收集機制有一項問題,就是它只復原記憶體,但是Java物件除了佔用記憶體之外,也可能佔用系統資源,如下程式,說明Java程式可能在產生exception時,沒有將檔案關閉…
為了處理這種狀況,Java提供了finalize的機制,在Object類別中有如下method…
JVM會在某物件沒有其它參考時執行該物件的finalize,而在實際收回物件所佔用的記憶體之前將系統資源復原,但需注意的是,Java語言規格中並未規定finalize一定要在殘餘記憶體收集的執行緒將物件丟棄之前立即執行,因此對程式設計師而言,還是無法保證finalize一定會執行,基於這樣的不確定因素,finalize被視為清除物件所佔用系統資源的”最後機會”,而不是復原系統資源的正常做法。
8. finalize是可以被override的,在上述程式你可以這麼override finalize…
需注意,收回系統資源之後,最好再呼叫上一層的finalize,以確保其它未被回收的系統資源被回收。
9. 雖然finalize有可能拋出exception,但是JVM會忽略該方法所拋出的exception。
ref:http://my.so-net.net.tw/idealist/Java/Basic/Garbage.html
1. 在Java的程式語言規格之中並未詳細說明殘餘記憶體收集機制的法則,因此每一家JVM的開發廠商都根據自己的演算法來研發殘餘記憶體收集機制。
2. 殘餘記憶體是以單獨的執行緒來執行的。
3. 通常JVM會在記憶體不足時啟動殘餘記憶體收集的執行緒。
4. 程式設計師可以透過以下兩種方法來”通知”JVM啟動殘餘記憶體收集:
Runtime.getRuntime().gc();
System.gc();
當程式設計師以上述兩種方法通知JVM啟動殘餘記憶體收集時,並不能保證JVM會啟動殘餘記憶體收集,事實上JVM只是在以上方法呼叫時”儘可能”執行殘餘記憶體收集。
5. 要確保不需要的物件會被殘餘記憶體機制收集掉的話,必須移除該物件的所有參考,移除參考的方法很簡單,如下… (將物件設為null即可)
MyObj m = new MyObj();
m.doSomethingUseful();
m = null;
6. 當一個method執行完離開它的區間時,所有區域物件都會自動被設為null,等待被回收。如下程式,當程式離開doSomething時,會產生三個垃圾物件,等待被回收。 (三個為陣列本身及陣列的兩個元素)
public class Question08 {
public static void main(String[] args) {
Question08 q08 = new Question08();
q08.doSomething(); //line 1
Thread.sleep(20000);
}
public void doSomething(){
Object[] objArray = new Object[2];
for(int i=0;i<objArray.length;i++){
objArray[i] = new Object();
}
}
}
7. 殘餘記憶體收集機制有一項問題,就是它只復原記憶體,但是Java物件除了佔用記憶體之外,也可能佔用系統資源,如下程式,說明Java程式可能在產生exception時,沒有將檔案關閉…
public void readData(String filename) {
FileInputStream fis;
try {
fis = new FileInputStream(filename);
fis.close();
fis = null;
}
catch(IOException e) { }
}
為了處理這種狀況,Java提供了finalize的機制,在Object類別中有如下method…
protected void finalize() throws Throwable { }
JVM會在某物件沒有其它參考時執行該物件的finalize,而在實際收回物件所佔用的記憶體之前將系統資源復原,但需注意的是,Java語言規格中並未規定finalize一定要在殘餘記憶體收集的執行緒將物件丟棄之前立即執行,因此對程式設計師而言,還是無法保證finalize一定會執行,基於這樣的不確定因素,finalize被視為清除物件所佔用系統資源的”最後機會”,而不是復原系統資源的正常做法。
8. finalize是可以被override的,在上述程式你可以這麼override finalize…
protected void finalize() throws Throwable {
if (fis != null) {
fis.close();
super.finalize();
}
}
需注意,收回系統資源之後,最好再呼叫上一層的finalize,以確保其它未被回收的系統資源被回收。
9. 雖然finalize有可能拋出exception,但是JVM會忽略該方法所拋出的exception。
ref:http://my.so-net.net.tw/idealist/Java/Basic/Garbage.html
上一篇: 2018-2019 ICPC, NEERC, Southern Subregional Contest D. Garbage Disposal
下一篇: Codeforces Round #511 (Div. 2) C - Enlarge GCD (数论, 暴力)
推荐阅读
-
Java Collection集合用法详解
-
【c#教程】C# 集合(Collection)
-
论基于数据访问的集合类(Data Access Based Collection)和领域
-
Java集合框架(一)Collection与Map的操作
-
PHP的Collection集合类
-
java集合Collection,Map及子类
-
java集合Collection,Map及子类
-
Collection中常用的方法 Iterator (迭代器) contains remove
-
Seaeast&collection——Object-oriented Programming(Java)_No.1 Java正则表达式Smalltalk
-
jdk源码阅读Collection详解