JDBC memory leak za 5,50-
Je libo si dát malý, únik paměti, který ve výsledku povede k pádu aplikace na java.lang.OutOfMemory? Budeme potřebovat tyto ingredience:
- kód pracující s databází přes JDBC
- poolování databázových připojení
To nejdůležitější ovšem představuje následující konstrukce
PreparedStatement pstmt = null;
try {
Connection con = //ziskej DB connection z poolu
pstmt = con.prepareStatement(“select …”);
//udelas dootaz, zpracujes bysledky
//a pak vytvoris novy statement, bez toho
//aniz by si uzavrel ten predchozi
pstmt = con.prepareStatement(“select …”);
} finally {
//ve finally sice zaviras statement,
//ale to se jedna samozrejme az o tu
//druhou instanci
DatabaseUtils.closeStatement(con, pstmt);
}
Vysvětlím proč k tomu memory leaku dochází, protože to není možná na první pohled patrné. I když je proměnná pstmt lokální a zdá se, že by garbage collector mohl z ní referencovaný objekt uklidit, není tomu tak. Statement je totiž ještě referencován z databázového připojení (con).
Protože jsou databázová připojení poolovaná, tak nezavřené statementy nich dohnívají do té doby, dokud nezaberou tolik paměti, že dojde k java.lang.OutOfMemory. Alespoň takovou zkušenost jsem udělal s Oracle JDBC driverem.
No a na závěr připomenu, že nejlepší ochranou je prevence třeba pomocí toho, že
starost o statement objekt necháte někomu jinému viz Návrhový vzor Template method a jeho aplikace v prostředí JDBC
Související články
Související epizody CZ Podcastu
- #3 · Java 6 SE, Vývoj webových aplikací
Dagi a Filemon o novinkách v Javě 6 a webových frameworcích.
- #1 · Vývojová prostředí v Javě
První díl CZ Podcastu se věnuje vývojovým prostředím pro Javu.