We are seeing Hibernate store a lot of information in the Session (first level cache) and eventually see OutOfMemory exceptions.
Environment
-
JBoss Enterprise Application Platform (EAP)
- 4
- 5
- 6
- 7
-
Hibernate
- 3.3.x
- 5.3.x (bundled with JBoss EAP 7.4)
-
Heap analyzer shows for Hibernate 3.3:
692,139,472 (32%) [88] 14 org/hibernate/engine/StatefulPersistenceContext 0x5ede0268 659,080,192 (31%) [24] 3 org/hibernate/util/IdentityMap 0x5ede0678 659,080,144 (31%) [32] 3 org/apache/commons/collections/SequencedHashMap 0x5ede0690 24 (0%) [24] 1 array of java/util/Map$Entry 0x5ede0700 96 (0%) [32] 22 class org/hibernate/util/IdentityMap 0x37fb9238 27,924,656 (1%) [48] 2 java/util/HashMap 0x5ede02c0 27,924,608 (1%) [994,528] 248,627 array of java/util/HashMap$Entry 0x87bc1c38 640 (0%) [32] 4 java/util/HashMap$Entry 0x9a1a2708 560 (0%) [32] 4 java/util/HashMap$Entry 0x9b0365e8 560 (0%) [32] 4 java/util/HashMap$Entry 0xb19044c8 -
For Hibernate 5, in the dominator tree of Eclipse Memory Analyzer shows an instance of
org.hibernate.engine.internal.StatefulPersistenceContextwith a large retained heap:Class Name | Shallow Heap | Retained Heap | Percentage ----------------------------------------------------------------------------------------------------------------- org.hibernate.engine.internal.StatefulPersistenceContext @ 0xce342030| 104 | 173,365,848 | 16.86% '- entitiesByKey java.util.HashMap @ 0xce342098 | 48 | 173,364,592 | 16.86% -----------------------------------------------------------------------------------------------------------------
Issue
- The application works fine for say 4 days at a stretch and then the JVM crashes with a OutofMemory error.
- We see a lot of memory being used by org/hibernate/
- We analyze this heap dump and we detect the high usage of org.hibernate.impl.SessionFactoryObjectFactory class (83% usage of memory).
Resolution
The session will grow this large when it has a very significant amount of objects living in it and can point to bad usage of the session. A few things that can lead to this are:
- Batch processing without eviction/clear, see the hibernate docs on this
This would fall over with an `OutOfMemoryException` somewhere around the 50,000th row. That is because Hibernate caches all the newly inserted
`Customer` instances in the session-level cache. In this chapter we will show you how to avoid this problem.
- The session having a longer scope than is required
- Doing queries without considering what they fetch
Regardless of the root cause the source is always loading many objects into the session without considering the implications.
This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.