JPA/HSQLDB is still eating all my memory
I'm working on a program that parses data from a file and stores it into a HSQLDB database. As the parser encounters data it creates entities which are mapped to the database using JPA/Hibernate. My problem is that while the parsing is being performed the application uses more and more memory. I have successfully used cached tables so that once the parsing is complete the memory is all released, but during the parsing it uses way more than what I am comfortable with.
I have tried to fix this by calling flush
and clear
methods on my EntityManager, but this had no effect. I've also tried to make sure that Entity with references to all other entities is kept in memory.
The largest objects in memory seems to be hsqldb.Sessions. Could it be that HSQlDb caches loads of data for each transaction? It does seem excessive to need 1GB of RAM to only end up with a DB that is 120MB on disk does it not?
Pl开发者_C百科ease advise on what I could try next.
Do a heap dump and use Eclipse MAT to analyse where the memory is used. With JPA the results are often surprising and without looking at the actual memory usage you're often stabbing in the dark.
After two days of faffing around with HSQLDB I followed the advice of two friends and changed database to H2. The memory footprint during a transaction is roughly a third now and it is also 20% faster.
Really surprised me
It could be different causes. I'd like to describe tools for memory leaks analysis: 1) first, find the process_id in your task manager;
2) then take a heap dump:
jmap -dump:live,format=b,file=<filename> <process_id>
3) then analyse it: a) JHAT util:
jhat <file>
b) (i recommend to) install Eclipse Memory Analyzer plugin from
http://download.eclipse.org/mat/1.3/update-site/
(Eclipse: help-> install new software ->add repository )
install it and go to its perspective. open and select option to find memory leaks.
In case of HSQLDB: usually MemoryAnalizer shows that memory used in
CompiledStatementManager.csidmap
-then make sure that you always call
statement.close()
精彩评论