The scenario that the memory issue may happen:
- One
EntityManagerFactoryand OneEntityManagerare used throughout the whole session; - The session contains a lot of queries, they are all read-only queries;
- Most queries are to retrieve database records based on primary keys;
- The records retrieved are approximately evenly distributed across primary keys;
- The database being queried has a large amount of data.
It seems that OpenJPA keeps references to data retrieved from the queries as cache. This prevents JVM garbage collecting them. Eventually, out of memory error happens.
This time, it seems that the call to
clear method on EntityManager does not even work. Finally, we added the following properties and it seemed to solve the issue:
openjpa.AutoDetach=nontx-read
In fact, it is not a good practice to use
EntityManager as shown in the scenario. Maybe the initial consideration is to re-use the single EntityManager as much as possible to help improve the performance of the session that is created in a batch process.In general, the
EntityManager object should not live in the whole long session. Instead it should be created on demand and closed and disregarded when finishing its unit of work. However, i haven't got time to test how worse the performance can degrade if it is implemented this way.
No comments:
Post a Comment