由close引起的故事

最近在寫一些多線程的任務,有時候任務處理多起來,一些很差的編程毛病就變得恐懼起來。 html

1. 採用框架,在讀取信息時候有些慢,因而我用原生jdbc來完成的。代碼以下:
java


public List<String> getIsbns(int offset, int size) {
		try {
			Connection con = dataSource.getConnection();
			Statement stmt = con.createStatement();
			ResultSet rs = stmt.executeQuery("select pisbn from amazon_book where flag is null limit " + offset + ", " + size);
			List<String> list = new ArrayList<String>(size);
			while (rs.next()) {
				list.add(rs.getString(1));
			}
			return list;
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return null;
	}



因爲,我沒有及時的關閉Connection,致使程序在運行不久後出現了問題。


狀況描述:
1. 採用直連方式,每次都須要建立鏈接,而鏈接又未釋放,致使保持過多數據庫鏈接資源,數據查詢結果響應下降。
2. 採用數據庫鏈接池方式,因爲沒有及時釋放資源,致使數據庫鏈接池達到最大的時候,使得其餘數據庫請求等待,致使數據庫訪問有一種靜默的樣子。 sql

查看java.sql.Connection源碼,發現有以下注釋 數據庫


/**
     * Releases this <code>Connection</code> object's database and JDBC resources
     * immediately instead of waiting for them to be automatically released.
     * <P>
     * Calling the method <code>close</code> on a <code>Connection</code>
     * object that is already closed is a no-op.
     * <P>
     * It is <b>strongly recommended</b> that an application explicitly
     * commits or rolls back an active transaction prior to calling the
     * <code>close</code> method.  If the <code>close</code> method is called
     * and there is an active transaction, the results are implementation-defined.
     * <P>
     *
     * @exception SQLException SQLException if a database access error occurs
     */
    void close() throws SQLException;



【咱們應該手動釋放不該用的資源,而不是等待被自動回收】,若是資源被消耗殆盡,只能等待虛擬機本身去回收了,這樣的程序不是高效的。



2. 在字符寫入文件時候,對於OutputStream沒有及時close 編程

try {
		File f = new File(bookFolder + "page.html");
		System.out.println(f.getPath());
		if (!f.getParentFile().exists()) {
			f.getParentFile().mkdirs();
		}
		if (!f.exists()) f.createNewFile();
		IOUtils.copy(new ByteArrayInputStream(doc.toString().getBytes()), new FileOutputStream(f));
	} catch (Exception e) {
		throw new RuntimeException(e.getMessage(), e);
	}



緣由:  
操做系統的中打開文件的最大句柄數受限所致,經常發生在不少個併發用戶訪問服務器的時候.由於爲了執行每一個用戶的應用服務器都要加載不少文件(new一個socket就須要一個文件句柄),這就會致使打開文件的句柄的缺少.

解決:
儘可能把類打成jar包,由於一個jar包只消耗一個文件句柄,若是不打包,一個類就消耗一個文件句柄.
java的垃圾回收不能關閉網絡鏈接打開的文件句柄,若是沒有執行close()(例如:java.net.Socket.close())則文件句柄將一直存在,而不能被關閉.你也能夠考慮設置socket的最大打開數來控制這個問題. 服務器

因此養成良好的編碼習慣,在對數據庫訪問,文件操做完畢後,經過finally模塊將其關閉,以避免發生沒必要要的問題。 網絡

相關文章
相關標籤/搜索