У меня есть некоторый код, который обращается к базе данных SQLite с помощью JDBC.
Я заметил, что каждый раз, когда делается запрос, использование памяти увеличивается - и оно не падает, даже после того, как соединениезакрыто.
Вот что я делаю:
1) Закрытие PreparedStatement
2) Закрытие ResultSet
3) Закрытие соединения
Вот скриншот анализа heapdump:
Показывает много java.lang.ref.Finalizer
и много PreparedStatement
и ResultSet
объекты.
Вот код (его в Scala, но он должен быть легко сопоставим с Java):
val conn: Connection = DriverManager.getConnection(url)
// Gets strings by a query like SELECT .. WHERE foo = ?
def getStringsByQuery(query: String, param: String, field: String):Seq[String] = {
val st = conn.prepareStatement(query)
st.setString(1, param) //value of foo = ?
st.setFetchSize(Integer.MAX_VALUE)
st.setMaxRows(Integer.MAX_VALUE)
//Holder of results
var results = collection.mutable.Seq.empty[String]
val rs: ResultSet = st.executeQuery()
//add results to holder
while (rs.next())
results :+= rs.getString(field)
rs.close() //closing ResultSet
st.close() //closing PreparedStatement
results
}
Вот тест, который я написал, чтобы проверить это:
test("detect memory leak") {
log.info("Starting in 10 sec")
Thread.sleep(10.seconds.toMillis)
//Calls a method over and over to see if there's a memory leak or not..
(1 to 1000).par.foreach(i => {
val randomWord = getRandomWord() //this produces a random word
val sql = "SELECT foo FROM myTable where bar = ?"
val results = getStringsByQuery(sql, randomWord, "bar")
})
conn.close() //close the connection
log.info("Closed conn, closing in 30 sec")
Thread.sleep(1.minutes.toMillis)
}
Когда я запускаю тест - использование памяти постоянно увеличивается с 24,6 ГБ до 33 ГБ и никогда не уменьшается (даже если ResultSet + PreparedStatement закрываются), и даже в конце, когда conn закрывается и поток спитв течение 1 минуты - использование памяти все еще не уменьшается.
Кто-нибудь знает, что здесь происходит?Буду признателен за любую помощь.