這是本文件的舊版!


使用Properties類別的Memory Leak

使用Properties類別來儲存組態設定是非常方便的事情。即使是知名的java語言教學,在建立檔案串流物件上,也常常忘記關閉它而造成記憶體遺失。好加在的是,這樣的錯誤可以find bug工具程式去發現。首先讓我說明問題所在:

	private void load(){
		mProp = new Properties();
		try {
			mProp.load(new FileInputStream(mConfigFilePath));
		} catch (IOException e) {
			// need to handle ..
		}
	}
 
	public void save(){
		try {
			mProp.store(new FileOutputStream(mConfigFilePath), "");
		} catch (IOException e) {
			// need to handle ..
		}
	}
上面程式碼的問題就在於FileInputStreamFileOutputStream建構後,完全沒做close的動作。相信在執行多次後,應該會開始出現效能下降或根本無法存取的問題。修改方法也相當簡單:
	private void close(Closeable closable){
		try {
			if( closable != null )
				closable.close();
		} catch (IOException e) {
			// log
		}
	}
 
	private void load(){
		mProp = new Properties();
		InputStream is = null;
		try {
			is = new FileInputStream(mConfigFilePath);
			mProp.load(is );
		} catch (IOException e) {
			// need to handle ..
		} finally {
			close(is);
		}
	}
 
	public void save(){
		OutputStream os = null;
		try {
			os = new FileOutputStream(mConfigFilePath);
			mProp.store(os, "");
		} catch (IOException e) {
			// need to handle ..
		} finally {
			close(os);
		}
	}
在使用之前先把它assign到local variable上,在finally的地方在執行close的動作即可,這種錯誤其實蠻多人會犯的。另外對於finally處理關閉串流的方式,許多人會把它寫成nested的try block,多層的try block不只不好閱讀,還可能變無窮的block地獄。對於這部分的處理,大家可以參考搞笑談軟工的幾篇文章: Checked or unchecked exceptions (2)敏捷式例外處理設計 (4):我到底哪裡做錯之 nested try block敏捷式例外處理設計 (6):我到底哪裡做錯之 unprotected main program,我相信可以增進不少功力。

友藏內心的獨白: 我的桌機還沒修好,但還是要有產出!