由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模块将其关闭,以避免发生没必要要的问题。 网络

相关文章
相关标签/搜索