讀古今文學網 > 編寫高質量代碼:改善Java程序的151個建議 > 建議51:不要主動進行垃圾回收 >

建議51:不要主動進行垃圾回收

很久很久以前,在Java 1.1的年代裡,我們經常會看到System.gc這樣的調用——主動對垃圾進行回收。不過,在Java知識深入人心後,這樣的代碼就逐漸銷聲匿跡了——這是好現象,因為主動進行垃圾回收是一個非常危險的動作。

之所以危險,是因為System.gc要停止所有的響應(Stop the world),才能檢查內存中是否有可回收的對象,這對一個應用系統來說風險極大,如果是一個Web應用,所有的請求都會暫停,等待垃圾回收器執行完畢,若此時堆內存(Heap)中的對象少的話則還可以接受,一旦對像較多(現在的Web項目是越做越大,框架、工具也越來越多,加載到內存中的對象當然也就更多了),那這個過程就非常耗時了,可能0.01秒,也可能是1秒,甚至是20秒,這就會嚴重影響到業務的正常運行。

例如,我們寫這樣一段代碼:new String("abc"),該對像沒有任何引用,對JVM來說就是個垃圾對象。JVM的垃圾回收器線程第一次掃瞄(掃瞄時間不確定,在系統不繁忙的時候執行)時把它貼上一個標籤,說「你是可以被回收的」,第二次掃瞄時才真正地回收該對象,並釋放內存空間,如果我們直接調用System.gc,則是在說「嗨,你,那個垃圾回收器過來檢查一下有沒有垃圾對象,回收一下」。瞧瞧看,程序主動招來了垃圾回收器,這意味著正在運行著的系統要讓出資源,以供垃圾回收器執行,想想看吧,它會把所有的對象都檢查一遍,然後處理掉那些垃圾對象。注意哦,是檢查每個對象。

不要調用System.gc,即使經常出現內存溢出也不要調用,內存溢出是可分析的,是可以查找出原因的,GC可不是一個好招數!