[英]mysql memory leak on my code?
我對 java 真的很陌生,我需要知道這是 memory 泄漏嗎?
這是我正在嘗試改進的游戲服務器的一段代碼:
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();
}
}
經過大量的思考和閱讀,我認為可能是一個finally catch 塊,其中包含 closePreparedStatement(p) 以避免 memory 泄漏是一個好主意?
finally
{
closePreparedStatement(p);
}
如果是這樣,那么我還有很多工作要做以這種方式更改數百種方法。 我只是在我以后后悔之前問你的意見,因為我是一個新手
需要一個答案,如果您對這段關於 memory 泄漏的代碼有任何意見,請不要猶豫。
感謝您的時間。
您的最終阻止假設是正確的。 例如,打開一個連接,然后代碼中出現錯誤。 幸運的是(在某種程度上)你有一個 try catch 塊,所以你可以捕捉然后做你可能處理的錯誤天氣它是拋出錯誤或顯示錯誤或記錄錯誤或以上所有(有很多方法可以處理有錯誤,每個錯誤都應該以一種或另一種方式處理)。 不幸的是,如果在 catch 塊中捕獲錯誤並且連接(可能是數據庫或文件等)仍然打開,則連接正在占用資源並迫在眉睫正在運行源的機器。最終阻止釋放此連接是KEY 如您的推測所預測的那樣。
如果有多個連接,則泄漏可能發生在其他地方。 根據經驗,最好使用 finally 塊來關閉在 try 塊中打開的連接。 快樂編碼!
給定代碼不可能給出最終答案,例如如何在newTransact
中檢索連接和語句。 你在哪里關閉連接?
一般來說,缺少final
子句是對的,但您必須注意,在大多數情況下,您的preparedstatement 已經關閉,只有在遇到異常時才會丟失。 總結:引入finally
塊是好的,但我敢打賭它不會解決您的 memory 泄漏問題。
您必須跟蹤您的應用程序以找出泄漏的可能位置!
嘗試在 finally 塊中關閉語句絕對是最佳實踐。
You should really look at wikipedia about JDBC: http://en.wikipedia.org/wiki/Java_Database_Connectivity There are very nice examples how to connect to database in Java without causing a memory leak.
edit: If you really have to connect to database using JDBC, I would recomend using Spring - there's a great class JdbcTemplate, which hides lots of boilerplate code and you can focus on the important stuff (getting data from/to database) and not worry關於 memory 泄漏。
如果您的以下語句中發生異常:
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();}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.