简单的mysql / jdbc代码导致内存泄漏?

时间:2018-01-11 07:08:52

标签: java jdbc heap-dump

我正在尝试分析堆转储,以便第一次找到内存泄漏。我正在使用MAT打开堆转储,很明显它是一个对象?这几乎占据了整个堆,它是一个sql类com.mysql.cj.jdbc.ConnectionImpl。

由于sql实际上只在我的代码的一部分中使用,所以它基本上必须是这里的一小部分代码......

static Connection getDBconn() {
    Connection conn = null;
    while (conn == null) {
        try {
            conn = DriverManager.getConnection(serverURL, user, pass);
        } catch (SQLException e) {
            Logger.logError(e);
        }
    }
    return conn;
}
static void update(String sql) {
    while (currConn == null)
        currConn = getDBconn();
    boolean error = false;
    do {
        try {
            currConn.createStatement().executeUpdate(sql);
        } catch (SQLException e) {
            try {
                currConn.close();
            } catch (SQLException e1) {
                Logger.logError(e1);
            }
            currConn = getDBconn();
            Logger.logError(e);
            error = true;
        }
    } while (error);
}
static ResultSet query(String sql) {
    while (currConn == null)
        currConn = getDBconn();
    ResultSet rs = null;
    while (rs == null) {
        try {
            rs = currConn.createStatement().executeQuery(sql);
        } catch (SQLException e) {
            try {
                currConn.close();
            } catch (SQLException e1) {
                Logger.logError(e1);
            }
            currConn = getDBconn();
            Logger.logError(e);
        }
    }
    return rs;
}

这段代码应该做的基本上是在一些方法中包装查询/更新语句,以确保每个命令总是最终执行,即使出现错误。我的程序会在很多时间内运行很多请求,我想确保它在不中断程序的情况下自动处理所有可能出现的问题。

我所写的内容大约需要一个小时左右,然后即使我的堆设置为8gb,也会出现内存错误,这显然有点过分。我还应该注意到我没有得到任何sql错误所以它甚至没有进入catch块。很明显,这段代码存在某种泄漏,但我无法弄清楚它可能是什么。任何建议都将受到赞赏,如果需要,我可以提供有关堆转储的更多信息。

1 个答案:

答案 0 :(得分:1)

当你不需要两次时,你就会得到连接

\

try { currConn.close(); } catch (SQLException e1) { Logger.logError(e1); } --> currConn = getDBconn(); Logger.logError(e); 之后删除currConn = getDBconn(),您就不会发生连接泄漏。

更好的是,即使没有发生错误,最后关闭连接:

currConn.close();

还创建一种方法来防止代码重复和关闭连接的不同实现。