我开启了一个服务端(derby server),然后使用一个程序去连接它,进行操作(select,insert,delete等操作).
但我发现运行两天以后derby的日志里出现outofmemery,导致服务端和调用它的客户端的进程都卡死了.现象: 客户端程序 和 derby server的内存一起动以后就开始不断增加.两天以后出现outofmem的异常.
以下是我调用数据库操作的api类.(客户端里 执行executeQuery以后,程序里进行了rsclose()的操作.)请问各位,这是什么问题呢? /**
 * 
 */
package com.ffcs.db;import java.sql.*;
import com.ffcs.util.*;public class SqlConn {
    String driver = "";
    String url = "";
    String userName = "";
    String userPassword = "";
    Connection conn = null;
    Statement stmt = null;
    ResultSet rset = null;    /**
     * 构造函数
     * @param SQLUrl
     * @param user
     * @param password
     * @param driver
     */
    public SqlConn(String SQLUrl, String user, String password, String driver) {
     this.driver = driver;
        this.url = SQLUrl;
        this.userName = user;
        this.userPassword = password;
    }    /**
     * 功能: openConnection打开数据库Connection的方法
     *      为打开Connection,读取位于类路径下的db.properties文件,载入配置信息
     * @param null
     * @return boolean
     */
    public boolean openConnection() {
        //加载JDBC驱动
        try {
            Class.forName(driver);
        } catch (ClassNotFoundException e) {
            LogUtil.DEALERROR_LOGGER.error("[SQLConn]_登陆SQL数据库出现错误" + e.getMessage());
            return false;
        }        //打开数据库Connection
        try {
            this.conn = DriverManager.getConnection(url, userName,
                    userPassword);
            
        } catch (SQLException e) {
            LogUtil.DEALERROR_LOGGER.error("[SQLConn]_生成SQL连接过程中出现错误" + e.getMessage());
            return false;
        }
        return true;
    }    /**
     * 功能:查询数据库的方法(SELECT)
     * @param query
     * @return java.sql.ResultSet
     */
    public ResultSet exceuteQuery(String query) throws SQLException {
        this.stmt = conn.createStatement();
        return stmt.executeQuery(query);
    }    /**
     * 功能:修改数据库的方法(UPDATE,INSERT,DELETE)
     * @param query,I_Bz是事务标志,true为要起事务,false为不起事务
     * @return void
     */
    public void exceuteUpdate(String query, boolean I_Bz) throws
            SQLException {
        if (I_Bz) {
            try {
                conn.setAutoCommit(false); //禁止自动提交,设置回滚点
                this.stmt = conn.createStatement();
                stmt.executeUpdate(query);
                if (stmt != null) {
                    stmt.close();
                }
                conn.commit(); //事务提交
            } catch (Exception ex) {
                LogUtil.DEALERROR_LOGGER.error("[SQLConn]_数据库出错 " + ex.getMessage());
                try {
                    conn.rollback(); //操作不成功则回滚
                } catch (Exception e) {
                    LogUtil.DEALERROR_LOGGER.error("[SQLConn]_数据库出错,回滚出错 " +
                                       e.getMessage());
                }
            }
        } else {
            this.stmt = conn.createStatement();
            stmt.executeUpdate(query);
            if (stmt != null) {
                stmt.close();
            }
        }
    }    /**
     * 功能:返回数据库链接的相关资料
     * @param 无
     * @return void
     */
    public void close() throws SQLException {        if (rset != null) {
            rset.close();
        }
        if (stmt != null) {
            stmt.close();
        }
        if (conn != null) {
            conn.close();
        }
    }
    
    public void rsetclose() throws SQLException {
        if (rset != null) {
            rset.close();
        }
        if (stmt != null) {
            stmt.close();
        }
    }    /**
     * 功能:从服务器回收资源
     * @param 无
     * @return void
     */
    public void finalize() throws Throwable {
        this.close();
    }    public Connection getcurrConn() {
        return this.conn;
    }
}

解决方案 »

  1.   

    从这里看不出来,要看是怎么调用这个类的。为保险起见,建议在 exceuteUpdate/exceuteQuery 里面加上 finally {this.close();} 比较好。
      

  2.   

    以下是我使用的方法.请看如下连接数据库
    con = new SqlConn(config.dbUrl, config.dbUserName, config.dbPasswd,
    config.driver);
    con.openConnection();
    LogUtil.BASEINFO_LOGGER.info("conn connect");使用,操作数据库
    String selectSql = "select * from a"
    + " where sended is null";
    rs = con.exceuteQuery(selectSql);
    while (rs.next()) {

    // 打上标记,下一次不再取
    String tagSql = "update  a set sended = 'y' where id = '"
    + id + "' and a= '" + alarm + "'";
    con.exceuteUpdate(tagSql, false);

    }
    rs.close();
    // 关闭占用的连接资源
    con.rsetclose();