ava中記憶體回收機制的原理推薦一篇文章:對高效能JAVA代碼之記憶體管理更甚者你寫的代碼,GC根本就回收不了,直接系統掛掉。GC是一段程式,不是智能,他只回收他認為的垃圾,而不是回收你認為的垃圾。GC記憶體回收:Grabage Collection相信學過JAVA的人都知道這個是什麼意思。但是他是如何工作的呢。首先,JVM在管理記憶體的時候對於變數的管理總是分新對象和老對象。新對象也就是開發人員new出來的對象,但是由於生命週期短,那麼他佔用的記憶體並不是馬上釋放,而是被標記為老對象,這個時候該對象還是要存在一段時間。然後由JVM決定他是否是垃圾對象,並進行回收。所以我們可以知道,垃圾記憶體並不是用完了馬上就被釋放,所以就會產生記憶體釋放不及時的現象,從而降低了記憶體的使用。而當程式浩大的時候。這種現象更為明顯,並且GC的工作也是需要消耗資源的。所以,也就會產生記憶體浪費。JVM中的對象生命週期裡談記憶體回收:對象的生命週期一般分為7個階段:建立階段,應用階段,不可視階段,不可到達階段,可收集階段,終結階段,釋放階段。建立階段:首先大家看一下,如下兩段代碼:test1:for( int i=0; i《10000; i++)Object obj=new Object();test2:Object obj=null;for( int i=0; i《10000; i++)obj=new Object();這兩段代碼都是相同的功能,但是顯然test2的效能要比test1效能要好,記憶體使用量率要高,這是為什麼呢。原因很簡單,test1每次執行for迴圈都要建立一個Object的臨時對象,但是這些臨時對象由於JVM的GC不能馬上銷毀,所以他們還要存在很長時間,而test2則只是在記憶體中儲存一份對象的引用,而不必建立大量新臨時變數,從而降低了記憶體的使用。另外不要對同一個對象初始化多次。例如:public class A{private Hashtable table = new Hashtable();public A(){ table = new Hashtable();// 這裡應該去掉,因為table已經被初始化。}這樣就new了兩個Hashtable,但是卻只使用了一個。另外一個則沒有被引用。而被忽略掉。浪費了記憶體。並且由於進行了兩次new操作。也影響了代碼的執行速度。應用階段:即該對象至少有一個引用在維護他。不可視階段:即超出該變數的範圍。這裡有一個很好的做法,因為JVM在GC的時候並不是馬上進行回收,而是要判斷對象是否被其他引用在維護。所以,這個時候如果我們在使用完一個對象以後對其obj=null或者obj.doSomething()操作,將其標記為空白,可以協助JVM及時發現這個垃圾對象。不可到達階段:就是在JVM中找不到對該對象的直接或者間接的引用。可收集階段,終結階段,釋放階段:此為回收器發現該對象不可到達,finalize方法已經被執行,或者對象空間已被重用的時候。JAVA的析構方法:可能不會有人相信,JAVA有解構函式。 是的,有。因為JAVA所有類都繼承至Object類,而finalize就是Object類的一個方法,這個方法在JAVA中就是類似於C++解構函式。一般來說可以通過重載finalize方法的形式才釋放類中對象。如:public class A{public Object a;public A(){ a = new Object ;}protected void finalize() throws java.lang.Throwable{a = null; // 標記為空白,釋放對象super.finalize(); // 遞迴調用超類中的finalize方法。}}當然,什麼時候該方法被調用是由JVM來決定的。..。..。..。..。..。..。..。.一般來說,我們需要建立一個destory的方法來顯式的調用該方法。然後在finalize也對該方法進行調用,實現雙保險的做法。由於對象的建立是遞迴式的,也就是先調用超級類的構造,然後依次向下遞迴調用建構函式,所以應該避免在類的建構函式中初始設定變數,這樣可以避免不必要的建立對象造成不必要的記憶體消耗。當然這裡也就看出來介面的優勢。數組的建立:由於數組需要給定一個長度,所以在不確定資料數量的時候經常會建立過大,或過小的數組的現象。造成不必要的記憶體浪費,所以可以通過軟引用的方式來告訴JVM及時回收該記憶體。(軟引用,具體查資料)。例如:Object obj = new char[10000000000000000];SoftReference ref = new SoftReference(obj);共用靜態儲存空間:我們都知道靜態變數在程式運行期間其記憶體是共用的,因此有時候為了節約記憶體工件,將一些變數聲明為靜態變數確實可以起到節約記憶體空間的作用。但是由於靜態變數生命週期很長,不易被系統回收,所以使用靜態變數要合理,不能盲目的使用。以免適得其反。因此建議在下面情況下使用:1,變數所包含的對象體積較大,佔用記憶體過多。2,變數所包含對象生命週期較長。3,變數所包含資料穩定。4,該類的對象執行個體有對該變數所包含的對象的共用需求。(也就是說是否需要作為全域變數)。對象重用與GC:有的時候,如資料庫操作對象,一般情況下我們都需要在各個不同模組間使用,所以這樣的對象需要進行重用以提高效能。也有效避免了反覆建立對象引起的效能下降。一般來說對象池是一個不錯的注意。如下:public abstarct class ObjectPool{private Hashtable locked,unlocked;private long expirationTime;abstract Object create();abstract void expire( Object o);abstract void validate( Object o);synchronized Object getObject(){。..};synchronized void freeObject(Object o){。..};這樣我們就完成了一個對象池,我們可以將通過對應的方法來存取刪除所需對象。來維護這快記憶體提高記憶體重用。當然也可以通過調用System.gc()強制系統進行記憶體回收操作。當然這樣的代價是需要消耗一些cpu資源。不要提前建立對象:盡量在需要的時候建立對象,重複的分配,構造對象可能會因為記憶體回收做額外的工作降低效能。JVM記憶體參數調優:強制記憶體回收對於系統自動的記憶體回收機制會產生負面影響,會加大系統自動回收的處理時間,所以應該盡量避免顯式使用System.gc(),JVM的設定可以提高系統的效能。例如:java -XX:NewSize=128m -XX:MaxNewSize=128m -XX:SurvivorRatio=8 -Xms512m -Xmx512m具體可以查看java協助文檔。我們主要介紹程式設計方面的效能提高。JAVA程式設計中有關記憶體管理的其他經驗:根據JVM記憶體管理的工作原理,可以通過一些技巧和方式讓JVM做GC處理時更加有效。,從而提高記憶體使用量和縮短GC的執行時間。1,儘早釋放無用對象的引用。即在不使用對象的引用後設定為空白,可以加速GC的工作。(當然如果是傳回值。..。.)2,盡量少用finalize函數,此函數是JAVA給程式員提供的一個釋放對象或資源的機會,但是卻會加大GC工作量。3,如果需要使用到圖片,可以使用soft應用類型,它可以儘可能將圖片讀入記憶體而不引起OutOfMemory.4,注意集合資料類型的資料結構,往往資料結構越複雜,GC工作量更大,處理更複雜。5,盡量避免在預設構造器(建構函式)中建立,初始化大量的對象。6,盡量避免強制系統做記憶體回收。會增加系統做記憶體回收的最終時間降低效能。7,盡量避免顯式申請數組,如果不得不申請數組的話,要盡量準確估算數組大小。8,如果在做遠程方法調用。要盡量減少傳遞的對象大小。或者使用瞬間值避免不必要資料的傳遞。9,盡量在合適的情況下使用對象池來提高系統效能減少記憶體開銷,當然,對象池不能過於龐大,會適得其反.