我是java的新手,我需要知道这是一个内存泄漏吗?
这是我试图改进的游戏服务器的一段代码:
private static void closePreparedStatement(PreparedStatement p)
{
try {
p.clearParameters();
p.close();
} catch (SQLException e) {e.printStackTrace();}
}
public static void UPDATE_ACCOUNT(Compte acc)
{
try
{
String baseQuery = "UPDATE accounts SET " +
"`bankGold` = ?,"+
"`bank` = ?,"+
"`level` = ?,"+
"`stable` = ?,"+
"`banned` = ?,"+
"`enemy` = ?"+
" WHERE `guid` = ?;";
PreparedStatement p = newTransact(baseQuery, dConnexion);
p.setLong(1, acc.getBankGold());
p.setString(2, acc.parseBankObjectsToDB());
p.setInt(3, acc.get_Lvl());
p.setString(4, acc.parseStable());
p.setInt(5, (acc.isBanned()?1:0));
p.setString(6, acc.parseEnemyListToDB());
p.setInt(7, acc.getGUID());
p.executeUpdate();
closePreparedStatement(p);
}catch(SQLException e)
{
LogClass.addErrorLog("MySQL ERROR: "+e.getMessage());
e.printStackTrace();
}
}
经过多次思考和阅读之后,我想也许一个最终 catch块,其中有一个closePreparedStatement(p),这样可以避免内存泄漏?
finally
{
closePreparedStatement(p);
}
如果是这样,那么我有很多工作要做,以这种方式改变数百种方法。 因为我是一个全新的人,所以我后来才后悔问你的意见。
请找一个答案,如果您对这段关于内存泄漏的代码有任何意见,请不要犹豫。
感谢您的时间。
答案 0 :(得分:1)
你的最终区块假设是正确的。比如说打开了一个连接,然后代码中出现错误。幸运的是(在某种程度上)你有一个尝试catch块,所以你可以抓住然后做你可能的错误天气它会抛出错误或显示错误或记录错误或所有上述(有很多方法来处理有错误,每个错误应该以某种方式处理)。不幸的是,如果在catch块中发现错误并且连接(可能是数据库或文件等)仍然打开,连接正在占用资源并且即将运行源正在运行的机器。最后阻止释放此连接ARE按照你的假设预测KEY。
如果有多个连接,则泄漏可能在其他地方发生。根据经验,最好使用finally块来关闭在try块中打开的连接。快乐的编码!
答案 1 :(得分:1)
鉴于代码,最终答案是不可能的,例如如何在newTransact
中检索连接和语句。你在哪里关闭连接?
一般来说,你错了final
条款是正确的,但是你必须要知道,在大多数情况下,你的预备陈述已经关闭,只有在异常时它才会被遗漏。总结:引入finally
块很好,但我敢打赌它不会解决你的内存泄漏问题。
您必须追踪您的申请,以找出泄密的位置!
答案 2 :(得分:1)
试图在finally块中关闭语句绝对是最好的做法。
你应该真正看一下关于JDBC的维基百科:http://en.wikipedia.org/wiki/Java_Database_Connectivity有很好的例子说明如何在Java中连接到数据库而不会导致内存泄漏。
编辑:如果你真的必须使用JDBC连接到数据库,我会建议使用Spring - 有一个很棒的类JdbcTemplate,它隐藏了很多样板代码,你可以专注于重要的东西(从数据库获取数据)而不用担心内存泄漏。
答案 3 :(得分:0)
如果您的以下声明中发生异常:
PreparedStatement p = newTransact(baseQuery, dConnexion);
然后p可能未初始化,当您尝试在finally块中关闭它时,它将生成错误。现在即使你的方法中有一个try catch来关闭语句,这也不是一个应该记录的错误,因为已经处理了原始错误。因此,我相信在尝试关闭它之前检查语句是否为null是这种方法的一个好习惯。所以修改你的方法可能会更好:
private static void closePreparedStatement(PreparedStatement p)
{
if (p!=null){
try {
p.clearParameters();
p.close();
} catch (SQLException e) {e.printStackTrace();}
}
}