java回收對象
① java垃圾回收的優點和原理是什麼回收機制是怎樣的
優點:a.不需要考慮內存管理, b.可以有效的防止內存泄漏,有效的利用可使用的內存, c.由於有垃圾回收機制,Java中的對象不再有"作用域"的概念,只有對象的引用才有"作用域"
原理:垃圾回收器是作為一個單獨的低級別的線程運行,在不可知的情況下對內存堆中已死亡的或者長期沒有使用的對象回收,但是不能實時的對某一對象或者所有對象進行垃圾回收。
垃圾回收機制:分代復制垃圾回收、標記垃圾回收、增量垃圾回收
GC(Gabage Collection)工作原理:當創建對象時,GC就開始監視這個對象的地址、大小以及使用情況。通常,GC採用有向圖的方式記錄和管理heap(堆)中的素有對象。通過這種方式確定哪些對象是「可達的」,哪些是「不可以達的」。
垃圾回收機制通常是作為一個單獨的低級別的線程運行,不可預知的情況下對內存堆中已經死亡的或者長時間沒有使用的對象進行清理,我們雖然可以調用System.gc()讓垃圾回收器運行,但依舊無法保證GC一定會執行。
② 在java中,對象什麼時候可以被垃圾回收
1. 引用計數器演算法
解釋
系統給每個對象添加一個引用計數器,每當有一個地方引用這個對象的時候,計數器就加1,當引用失效的時候,計數器就減1,在任何一個時刻計數器為0的對象就是不可能被使用的對象,因為沒有任何地方持有這個引用,這時這個對象就被視為內存垃圾,等待被虛擬機回收
優點
客觀的說,引用計數器演算法,他的實現很簡單,判定的效率很高,在大部分情況下這都是相當不錯的演算法
其實,很多案例中都使用了這種演算法,比如 IOS 的Object-C , 微軟的COM技術(用於給window開發驅動,.net裡面的技術幾乎都是建立在COM上的),Python語言等.
缺陷
無法解決循環引用的問題.
這就好像是懸崖邊的人採集草葯的人, 想要活下去就必須要有一根繩子綁在懸崖上. 如果有兩個人, 甲的手拉著懸崖, 乙的手拉著甲, 那麼這兩個人都能活, 但是, 如果甲的手拉著乙, 乙的手也拉著甲, 雖然這兩個人都認為自己被別人拉著, 但是一樣會掉下懸崖.
比如說 A對象的一個屬性引用B,B對象的一個屬性同時引用A A.b = B() B.a = A(); 這個A,B對象的計數器都是1,可是,如果沒有其他任何地方引用A,B對象的時候,A,B對象其實在系統中是無法發揮任何作用的,既然無法發揮作用,那就應該被視作內存垃圾予以清理掉,可是因為此時A,B的計數器的值都是1,虛擬機就無法回收A,B對象,這樣就會造成內存浪費,這在計算機系統中是不可容忍的.
解決辦法
在語言層面處理, 例如Object-C 就使用強弱引用類型來解決問題.強引用計數器加1 ,弱引用不增加
Java中也有強弱引用
2. 可達性分析演算法
解釋
這種演算法通過一系列成為 "GC Roots " 的對象作為起始點,從這些節點開始向下搜索所有走過的路徑成為引用鏈(Reference Chain) , 當一個對象GC Roots沒有任何引用鏈相連(用圖論的話來說就是從GC Roots到這個對象不可達),則證明此對象是不可用的
優點
這個演算法可以輕松的解決循環引用的問題
大部分的主流java虛擬機使用的都是這種演算法
3. Java語言中的GC Roots
在虛擬機棧(其實是棧幀中的本地變數表)中引用的對象
在方法區中的類靜態屬性引用對象
在方法區中的常量引用的對象
在本地方法棧中JNI(即一般說的Native方法)的引用對象
③ java 被引用的對象怎麼回收
java對象符合以下條件便會被垃圾回收:
1.所有實例都沒有活動線程訪問。
2.沒有被其他任何實例訪問的循環引用實例。
3.Java 中有不同的引用類型。判斷實例是否符合垃圾收集的條件都依賴於它的引用類型。
④ 在java中,對象什麼時候可以被垃圾回收
通俗的說明白兩點就理解了:
不用的對象,或者說無法再調用的對象會被回收
垃圾回收不是實時的,也就是只能考慮最早什麼時候會被回收
Objectobj=newObject();//創建了一個對象,並定義一個變數obj指向它
obj=newObject();//又創建了一個對象,並將變數obj指向它,這時第一步創建的對象就被看作垃圾
註:你會了解,被看做垃圾的對象,是不會被程序再次調用的(即確實是垃圾)
⑤ java 怎麼對一個對象強制垃圾回收
一、Java提供finalize()方法,垃圾回收器准備釋放內存的時候,會先調用finalize()。
(1).對象不一定會被回收。
(2).垃圾回收不是析構函數。
(3).垃圾回收只與內存有關。
(4).垃圾回收和finalize()都是靠不住的,只要JVM還沒有快到耗盡內存的地步,它是不會浪費時間進行垃圾回收的。
二、垃圾回收器:
1、在 Java 中,當創建一個對象時,Java 虛擬機(JVM)為該對象分配內存、調用構造函數並開始跟蹤你使用的對象。當停止使用一個對象(就是說,當沒有對該對象有效的引用時),JVM 通過垃圾回收器將該對象標記為釋放狀態。
2、當垃圾回收器將要釋放一個對象的內存時,調用該對象的finalize() 方法(如果該對象定義了此方法)。垃圾回收器以獨立的低優先順序的方式運行,只有當其線程掛起等待該內存釋放的情況出現時,才開始運行釋放對象的內存。(事實上,可以調用System.gc() 方法強制垃圾回收器來釋放這些對象的內存。)
3、在以上的描述中,有一些重要的事情需要注意。首先,只有當垃圾回收器釋放該對象的內存時,才會執行finalize()。如果在 Applet 或應用程序退出之前垃圾回收器沒有釋放內存,垃圾回收器將不會調用finalize()。
三、finalize()方法的優缺點:
1、根據 Java 文檔,finalize() 是一個用於釋放非 Java 資源的方法。但是,JVM 有很大的可能不調用對象的finalize() 方法,因此很難證明使用該方法釋放資源是有效的。
2、Java 1.1 通過提供一個System.runFinalizersOnExit() 方法部分地解決了這個問題。(不要將這個方法與 Java 1.0 中的System.runFinalizations() 方法相混淆。)不象System.gc() 方法那樣,System.runFinalizersOnExit() 方法
總結:並不立即試圖啟動垃圾回收器。而是當應用程序或 Applet 退出時,調用每個對象的finalize() 方法。
⑥ java 裡面如何盡快回收不用的對象
finalize方法是java.lang.Object里定義的方法,因為所有java對象繼承於Object,因此每個對象都可以去實現這個方法。這個方法會在一個對象被垃圾回收時調用。
為c1,c2賦值為null可以使剛建立的兩個circle對象處於「沒有被引用」的狀態(通俗的說,就是沒有句柄指向這個對象,注意java沒有指針的概念),這種狀態下可以被垃圾回收。
而System.gc(),所謂gc就是garbage collection, 這個方法其實就是建議jvm去回收可以被垃圾回收的對象。 這個方法並不常用,因為一般垃圾回收都是自動完成的,並不需要人為控制。在這個例子中,只是為了能盡快看到finalize的執行。
注意java的垃圾回收機制有很大的不確定性,你不能確保某個可以被回收對象什麼時候被回收,所以gc只是「建議」,並不能「確保」。
⑦ Java 的垃圾回收如何判斷哪個對象可以被回收
java對象符合以下條件便會被垃圾回收:
1.所有實例都沒有活動線程訪問。
2.沒有被其他任何實例訪問的循環引用實例。
3.Java 中有不同的引用類型。判斷實例是否符合垃圾收集的條件都依賴於它的引用類型。
在編譯過程中作為一種優化技術,Java編譯器能選擇給實例賦null值,從而標記實例為可回收。
classAnimal{
publicstaticvoidmain(String[]args){
Animallion=newAnimal();
System.out.println("Mainiscompleted.");
}
protectedvoidfinalize(){
System.out.println("RestinPeace!");
}
}
⑧ java中可以主動回收人為認定的垃圾對象嗎
答案是不可以!
java的gc機制是在底層設計的,可以讓程序員不用想c語言那樣回收對象,是為了編程方便和安全考慮的,如果人為可以回收的話,安全性就不能保證了,所以不能主動回收。
在代碼中,對一些大對象,比如集合等,可以在方法結尾處,寫上 list = null ,這樣的,有利於gc的回收(未考證),另外可以在代碼中用 System.gc(); 來執行垃圾回收,但是並不能控制回收哪些無用對象,這個操作知識顯式地執行回收動作,但是回收的規則還是按照自動回收來的,所以即便是無用的對象,也可能回收,可能不回收。