文档章节

由close引发的故事

艳沐石
 艳沐石
发布于 2014/06/04 14:42
字数 765
阅读 10
收藏 0

最近在写一些多线程的任务,有时候任务处理多起来,一些不好的编程毛病就变得恐惧起来。

1. 采用框架,在读取信息时候有些慢,于是我用原生jdbc来完成的。代码如下:


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. 采用数据库连接池方式,由于没有及时释放资源,导致数据库连接池达到最大的时候,使得其他数据库请求等待,导致数据库访问有一种静默的样子。

查看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模块将其关闭,以免发生不必要的问题。


© 著作权归作者所有

共有 人打赏支持
艳沐石
粉丝 2
博文 41
码字总数 21947
作品 0
朝阳
程序员
《人之彼岸》书评|你也担忧人工智能吗?

郝景芳说,“人之彼岸”的意思很简单,人在此岸,AI在彼岸,对彼岸的遥望让我们观照此案。那么,假设我们到达了彼岸,人工智能时代,会发生什么样的故事呢? 人工智能一直是热度很高的话题,...

miss棋落
2017/12/12
0
0
java socket 注意的地方

关于 socket的关闭,有3种方法可以关闭socket连接 socket.close() socket.getOutputStream().close() #socket关闭后调用该方法会抛异常 socket.getInputStream().close() #socket关闭后调用该...

疯狂的骑士
2015/08/12
0
0
风行电视包机暖心热评上天 实力演绎从屏到心

  近日,“风行电视”号暖心专机刷爆网络,铺满飞机的扎心评论和客厅故事,不仅带领大家回味过去的客厅时光,引发一场关于客厅的回忆杀,也使得风行电视被更多人所熟知。   #看见客厅的温...

大数据头条
2017/12/19
0
0
浅谈软件项目规模估计——怎么估?

做事所花费的时间总是比你预期的要长,即使你的预期中考虑了侯世达定律。 —— 侯世达,哥德尔、埃舍尔、巴赫 侯世达 周三的下午,我像平常一样,写着代码听着歌,突然从天而降一份莫名其妙...

ThoughtWorks中国
2017/12/04
0
0
预示敏捷方法走偏的15个标志——第1部分

【编者按】误解和“最佳实践”可能会让你的团队原地打转,无法高效产出代码。本文主要介绍预示着敏捷方法走偏的15个标志,作者为 Steven A. Lowe。文章系国内 [ITOM][1] 管理平台 [OneAPM][2...

OneAPM蓝海讯通
2016/06/16
19
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

[MicroPython]STM32F407开发板驱动OLED液晶屏

1.实验目的 1.学习在PC机系统中扩展简单I/O 接口的方法。 2.进一步学习编制数据输出程序的设计方法。 3.学习 F407 Micropython开发板控制OLED显示字符。 2.所需元器件 F407 Micropython开发板...

bodasisiter
27分钟前
0
0
php require和include 相对路径一个有趣的坑

以前总是被教育,不要使用相对路径,这样性能比较差,但是相对路径的问题不仅仅是性能哦,看下面这里例子 这是项目结构 .├── main.php├── t│ ├── t1.php│ └── t2.php└─...

anoty
28分钟前
15
0
x64技术之SSDT_Hook

测试环境: 虚拟机: Windows 7 64bit 过PG工具 驱动加载工具 PCHunter64 系统自带的计算器和任务管理器等 实现思路: 实际思路与win32的思路一样.都是替换SSDT表里边的函数地址.不过微软被搞怕...

simpower
29分钟前
0
0
TreeMap源码分析,看了都说好

一、简介 TreeMap最早出现在JDK 1.2中,是 Java 集合框架中比较重要一个的实现。TreeMap 底层基于红黑树实现,可保证在log(n)时间复杂度内完成 containsKey、get、put 和 remove 操作,效率很...

Java小铺
39分钟前
0
0
协变、逆变

概念 假设 A、B表示类型 ≤ 表示继承关系 f<⋅>表示类型转换 若A ≤ B,则 A是B的子类,B是A的超类 协变、逆变 什么是型变?型变(type variance)允许对类型进行子类型转换。 为了下面讲解先...

obaniu
45分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部