We are seeing Hibernate store a lot of information in the Session (first level cache) and eventually see OutOfMemory exceptions.

Solution Verified - Updated

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.StatefulPersistenceContext with 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.

Components

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.