当前位置:编程学习 > JAVA >>

使用BoneCP连接池出现异常 内存泄露

使用BoneCP连接池,出现了“BoneCP detected an unclosed connection (in pool '***pool') and will now attempt to close it for you. You should be closing this connection in your application - enable connectionWatch for additional debugging assistance.”的异常。
我是在Tomcat中配置了JNDI,然后每次查询数据库时用下面两个类SqlConnection和SqlConnection来实现:
package db;

import java.sql.Connection;
import java.sql.SQLException;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
import com.mysql.jdbc.*;
/* 
*使用数据库连接池,具体配置在%catalinahome%/conf/sever.xml的<context><resource>节点中
*/
public class SqlConnection {
private DataSource ds = null;
Connection conn =null;
public SqlConnection(){
//通过JNDI获得数据源        
        try {
               InitialContext ctx=null;
               ctx = new InitialContext();
               ds=(DataSource)ctx.lookup("java:comp/env/jdbc/lxtjngJNDI");
        } catch (NamingException e) {
               e.printStackTrace();
        }   
}

public Connection getConnection() {
try{
return conn=ds.getConnection();
}catch(Exception ex){
System.out.print("数据库连接池初始化异常,信息是:"+ex.getMessage());
ex.printStackTrace();
return null;
}
}
// /////////////////////////////////////////////////////////////////////////////
/**
* 关闭连接
*/
public void close() {
try {
if (conn != null) {
conn.close();
conn = null;
}
} catch (SQLException se) {
System.out.println("close error: " + se.getMessage());
}   
finally {
   // Always make sure result sets and statements are closed,
   // and the connection is returned to the pool
   
   if (conn != null) {
     try { conn.close(); } catch (SQLException e) {e.printStackTrace(); }
     conn = null;
   }
 }

}

}
//////另一个类////////////////////////////////////////
package db;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class SqlExe {
ResultSet rs =null;
Statement stmt=null;
int count = 0;// 结果记录集中记录条数
String errorMsg = "";
public SqlExe() {

}

// 执行查询语句的函数
// para sql:数据库查询语句体sql
// return ResultSet
public ResultSet executeQuery(String sql,Connection conn) {
try{
stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
rs = stmt.executeQuery(sql);
 
  }
catch(SQLException ex){
System.err.println("数据库查询失败in db.executeQuery: sql="+sql +"\r\n"+ ex.getMessage());
this.errorMsg = "查询数据失败!sql="+sql +"\r\n"+ ex.getMessage();
this.close();
}
return rs;
}

// /////////////////////////////////////////////////////////////////////////

/*----------执行数据库更改(增加、删除、替换)操作,返回boolean,表示是否更改成功--------------------///

*/
public boolean executeUpdate(String sql,Connection conn) {
boolean bupdate = false;
rs = null;
try {
stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_UPDATABLE);
int rowCount = stmt.executeUpdate(sql);// 如果不成功,bupdate就会返回0
if (rowCount != 0) {
bupdate = true;
this.count = rowCount;
}
} catch (SQLException ex) {
System.err.println("数据库更新db.executeUpdate失败: sql="+sql +"\r\n"+ ex.getMessage());
this.errorMsg = "查询数据失败!sql="+sql +"\r\n"+ ex.getMessage();
this.close();
this.count =-1;
}
/*finally{
this.close();
}*/
return bupdate;
}

/*-----------------------执行数据库更改(增加、删除、替换)操作,返回所操作的行数------------------------///

*/
public int exeUpdate(String sql,Connection conn, String errorMsg) {

rs = null;
try {
stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_UPDATABLE);
int rowCount = stmt.executeUpdate(sql);
return this.count = rowCount;
} catch (SQLException ex) {// 如果不成功,bupdate就会返回-1
System.err.println("数据库更新db.executeUpdate失败: sql="+sql+"\r\n"+ ex.getMessage());
this.close();
if (errorMsg == null || errorMsg.length() == 0) {
this.errorMsg = "查询数据失败!sql="+sql +"\r\n"+ ex.getMessage();
} else
this.errorMsg = errorMsg;
return this.count =-1;
}
/*finally{
this.close();
}
*/
}

// /////////////////////////////////////////////////////////////////////////////
/**
* 关闭连接
*/
public void close() {
try {
if (rs != null) {
rs.close();
rs = null;
}
if (stmt != null) {
stmt.close();
stmt = null;
}
} catch (SQLException se) {
System.out.println("close error: " + se.getMessage());
} finally {
if (rs != null) {
     try { rs.close(); } catch (SQLException e) { ; }
     rs = null;
   }
   if (stmt != null) {
     try { stmt.close(); } catch (SQLException e) { ; }
     stmt = null;
   }
}
}
}
/////////////////////////////////////////////////////
下面是调用这两个类来实现数据库查询
Connection conn = new SqlConnection().getConnection();
SqlExe sqlExe = new SqlExe();
if (null != conn) {
    ResultSet rsGg=sqlExe.executeQuery(sql,conn);  
    ​if(rsGg.next()){
       out.print(rsGg.getString("code"));}
   else{
     out.print("广告burnmeSec950-90-1");
   }
    rsGg.close();
}
sqlExe.close();conn.close();
/////////////////////////////////////////
从调用来看,我关闭了ResultSet,Statement和Connection对象,但是BoneCp提示我有未关闭的连接,并且程序运行非常缓慢,占用内存非常高,最终宕机。
请教高手,我的做法哪里错了,为什么存在内存泄露?最好指出具体语句或方法,以及该如何改正,谢谢!
祥见百度空间http://hi.baidu.com/joyrising899
内存泄露 数据库连接池 tomcat BoneCP未关闭连接 波米生活网
补充:Java ,  Java SE
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,