臺北市去年開始實施垃圾費隨袋征收之后,垃圾量減少了許多,資源回收量也開始大增,大家都說這是個不錯的政策。此次春節前,臺北市政府為了便民,宣布兩天開放不收垃圾費(不需專屬垃圾袋),結果換來的是一場垃圾清運人員的噩夢。大量的垃圾堆積在各巷道路口,臺北市成了垃圾城。
不過這樣的場景我可是處變不驚了。畢竟我的大學時代四年是在中壢度過,這四年中,中壢市不斷地發生垃圾風波,有時候甚至整個桃園地區都浸在酸敗腐臭的垃圾堆中,我常常騎車騎一半就要停在路邊嘔吐一番,然后暈眩著繼續上路,到了目的地之后,整個人都虛脫了。經過了這樣的大風大浪,你說我怎么會把臺北市的這些垃圾放在眼里,更何況臺北市的這些垃圾還大都是「新鮮」的,不像當時中壢的垃圾是一兩周或一兩個月的(寫到這里,我打字的手顫抖起來)。
垃圾問題在現實生活中令人頭痛,垃圾問題在軟件技術圈子同樣令人頭痛。
自動內存管理也就是俗稱的垃圾收集(garbage-collection),可以讓程序員減輕許多負擔,也減少程序員犯錯的機會,所以相當受歡迎。從早期的 Smalltalk,Eiffel,到近期的 Java,C#,Python,REBOL,Ruby... 等,通通支持垃圾收集。垃圾收集差不多已經成了新一代高階程序語言必備的功能。
在 Java 中,你不需要主動刪除對象,而是由 Java 虛擬機器代勞。Java 虛擬機器會「持續追蹤」每個對象被使用的情形,如果某對象未被用到,Java 虛擬機器就會自動將其釋放。而要如何「持續追蹤」,實作細節留給 Java 虛擬機器的實作者發揮。
在早期,許多虛擬機器只是將垃圾收集實作成一個執行緒,一再進行檢查,遇到垃圾就釋放其內存。因為垃圾收集應該盡量不要影響到原程序的執行,所以虛擬機器將此執行緒的優先權設為 0(最低)。如此一來,當系統有其它執行緒在運作時,就不會進行垃圾收集,所以常常很久才會收集到垃圾,造成內存不足。但又不能因此調高其優先權,否則對 Java 的執行效率是一大打擊。所以,我們這些 Java 程序員的計算機 RAM 都要至少 256 MB,否則根本沒辦法順利執行 JBuilder 或 VisualAge for Java 等 Java 開發工具,因為這些開發工具本身就是專門吃內存的 Java 程序。我甚至在我的筆記型計算機上裝了 512MB 的 RAM。
于是許多人懷念起 C/C++ 來了,他們認為如果 Java 能同時支持自動內存管理和手動內存管理,那么該有多好!他們甚至希望 Java 未來的版本能允許他們主動釋放內存,比方說:
MyBigObject obj = new MyBigObject();
// do something here...
delete obj;
如果你也這么希望的話,我勸你早點死了這條心吧!Java 語言的主要精神之一是 robust,如果 Java 同時支持這兩種內存管理的話,可能會造成程序中有許多潛在的 Bug,內存不當存取的問題會比 C/C++ 更嚴重,所以是不可能這么做的。
java.lang.System.gc()
或
java.lang.Runtime.gc()
的
gc
指的就是 garbage-collection,不過根據文件的說明,它的作用只是「建議」Java 虛擬機器快去收垃圾,而不「保證」會去收垃圾。文件都寫得如此謙虛了,你也不應該對它寄予太多厚望。對于內存資源消耗太多的缺失,目前你能做的是:
-
改用一個內存管理方式好一點的虛擬機器:垃圾收集是一個豐富又龐大的主題。垃圾收集的算法有數百種可能,而且各有專長。許多虛擬機器采用的算法都不太一樣,建議各位多去比較幾家。
-
少制造垃圾:許多時候你制造了一堆不該制造的垃圾,比方說:該用固定式數組的時候卻用
Vector
,該用
StringBuffer
的時候卻用
String......
等等。這么會制造垃圾,再多內存也不夠用。
-
不再使用的對象要盡早設定為
null
,以便早點被當成垃圾清掉。
-
花錢多買一些
RAM
(砸錢解決問題,這是我最愛用的方式)。
垃圾,真的這么讓人討厭嗎?那倒不盡然,我最喜歡的樂團之一就叫做垃圾(Garbage),主唱雪莉曼森(Shirley Manson)的聲音真是迷死人了。比起名字很囂張,但歌聲是垃圾的那些偶像,這時候雪莉曼森的垃圾儼然成了一種諷刺。
?