作者: 赵杨 笔名:bootcool
[[email protected],[email protected]]
美丽而温暖的昆明其实很适合做冷静的思考
进一步提高JDBC应用程序的性能(三)
三: 优化数据库连接
在优化Java编写的程序时,对象重用是一个经常使用的方法。其中关键的一点,就是要尽量的重用一个已有的对象,而不是反复的创建一个新的对象。这样不仅能减少对内存的消耗,也降低了程序因为不断创建新对象而导致内存溢出的情况。由于建立一个数据库连接或者撤销一个连接都是代价昂贵的操作,所以重用一个Connection就是理所当然的了。我们有两种方式重用一个Connection:
方法 |
方法说明 |
使用环境 |
1 |
为每个用户建立一个单独的连接,并反复使用该连接创建语句,执行相关的数据库操作。 |
每个用户必须经过验证才能使用该连接。 |
2 |
建立连接池 |
多用户 |
(表 5)
我们使用完一个连接后一定要将其关闭,否则可能会因为连接资源耗尽,而导致程序性能降低,甚至使程序崩溃。
关闭联接有以下四种方式:
(1):不关闭连接
(2): // ……
Connection con = DriverManager.getConnection(url,user,password);
con = null;
// ……
(3): // ……
Connection con = DriverManager.getConnection(url,user,password);
con.close();//显示的关闭连接
// ……
(4):// ……
Connection con = DriverManager.getConnection(url,user,password);
con.close();//显示的关闭连接
con = null;
// ……
下面我们给出一些测试数据,通过比较我们不难得出关闭连接的正确方式:
首先我们给出测试程序,我们创建100个线程,每个线程都各自获得1个数据库连接。这里的每个线程就好比一个希望连接数据库的用户。
TestJdbc.java
import java.sql.Connection; import java.sql.DriverManager;
public class TestJdbc {
public TestJdbc() {
}
public void connect(){
try{ Class.forName("sun.jdbc.odbc.JdbcOdbcDriver").newInstance(); }
catch(Exception ex){ ex.printStackTrace(); }
//创建100个线程
for(int i=0;i<100;i++){ MakeConnection makeConnect = new MakeConnection(); makeConnect.setName(""+i+""); makeConnect.start(); } }
public static void main(String args[]){ TestJdbc test = new TestJdbc(); test.connect(); }
class MakeConnection extends Thread {
public MakeConnection () {
}
//创建1个连接 public void run(){
try { Connection con =null; //关闭连接的方式,可以是上述4种方式之一 con = DriverManager.getConnection("jdbc:odbc:test"); con.close(); con = null; }
catch(Exception e){ e.printStackTrace(); } }
}
测试一:Java堆内存分配最小为0Kb,最大为2000Kb
|
方式1 |
方式2 |
方式3 |
方式4 |
预期创建连接数目(个) |
100 |
100 |
100 |
100 |
创建及关闭连接耗时(毫秒) |
6,540 |
7,850 |
20,320 |
13,950 |
实际生成连接实例数(个) |
100 |
100 |
100 |
100 |
剩余连接实例数 (个) |
26 |
24 |
24 |
23 |
创建连接消耗内存量(字节) |
8,800 |
8,800 |
8,800 |
8,718 |
剩余连接占用内存量(字节) |
2,288 |
2,112 |
2,112 |
2,024 |
(表 6)
从测试一的数据我们看不出四种方式有什么太大的差别,这是因为Java堆分配的太小,当程序的内存消耗过大时,垃圾回收线程就自动回收那些无用的对象实例,从而影响了我们的测试结果。我们尝试分配一个更大的Java堆,以排除垃圾回收机制对测试结果的影响。
测试二:Java堆内存分配最小为0Kb,最大为20,000Kb
|
方式1 |
方式2 |
方式3 |
方式4 |
预期创建连接数目(个) |
100 |
100 |
100 |
100 |
创建及关闭连接耗时(毫秒) |
6,650 |
6,430 |
9,280 |
9,610 |
实际生成连接实例数(个) |
63 |
65 |
100 |
100 |
剩余连接实例数 (个) |
63 |
65 |
100 |
100 |
创建连接消耗内存量(字节) |
5,544 |
5,720 |
8,800 |
8,800 |
剩余连接占用内存量(字节) |
5,544 |
5,720 |
8,800 |
8,800 |
(表 7)
说明:(1) 剩余连接实例数是指没有被垃圾回收的连接数。
(2) (表7)中剩余连接实例数与实际生成连接实例数相同,说明在程序运行期间都没有进行垃圾回收。
从(表7)中我们看出方式1和方式2实际生成连接数小于预期创建连接数目,可能是因为没有显示的关闭连接造成的。考虑到垃圾回收的不确定性,我们最好采用方式3或者方式4来显示的关闭连接,这样做是最可靠的方法。
以下几部份将在进一步提高JDBC应用程序的性能(二)中详细介绍,包括笔者程序中的详尽代码。
四:使用预编译语句和批量更新
五:通过对象引用,重用结果集
六:使用可滚动的结果集合实现对数据进行分页显示
七: 其它提升JDBC性能的策略和技巧
赵杨:2002.3.31
参考文章:
http://java.sun.com/j2se/1.3/docs/guide/jdbc/getstart/GettingStartedTOC.fm.html

|