Memory Leaks after COMMIT operation (checked on versions 2.6.5 & 2.6.6.b01)

#1

During import big logs we are observed some memory leaks inside of ObjectDb, so, could you explain what we did incorrectly or investigate how to fix it ASAP.

Source code which causing memory leaks:

m_EntityMgrFactory = Persistence.createEntityManagerFactory( "objectdb:" + aFilename );
m_EntityManager = m_EntityMgrFactory.createEntityManager();
m_EntityManager.setFlushMode( FlushModeType.COMMIT );

if ( m_EntityManager.isOpen()  )
{
      m_EntityManager.getTransaction().begin();

      for ( Pa3DataKey dataKey : aDataKeys )
      {
         m_EntityManager.persist( dataKey );
      }

      m_EntityManager.getTransaction().commit();

      m_EntityManager.flush();
      m_EntityManager.clear();
      m_EntityManager.close(); 
}

After executing code above (write a 10-15 Mbytes) need to check remaining memory in any available profiler. Stack trace for mentioned code below:

+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------+----------------------+
|                                                                                 Name                                                                                  |     Objects      |         Size         |
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------+----------------------+
|  +---<Objects without allocation information>                                                                                                                         |  411,085         |  104,054,912         |
|  |                                                                                                                                                                    |                  |                      |
|  +---<All threads>                                                                                                                                                    |   28,939  100 %  |   16,588,016  100 %  |
|    |                                                                                                                                                                  |                  |                      |
|    +---java.lang.Thread.run()                                                                                                                                         |   21,513   74 %  |    8,151,472   49 %  |
|    | |                                                                                                                                                                |                  |                      |
|    | +---com.anritsu.pa3.plugins.imports.ttcn3xml.parsers.TTCN3XmlParser.run()                                                                                        |   11,760   41 %  |    4,261,872   26 %  |
|    | | |                                                                                                                                                              |                  |                      |
|    | | +---com.anritsu.pa3.plugins.imports.ttcn3xml.parsers.TTCN3XmlParser.parse(InputStream)                                                                         |   11,137   38 %  |    4,169,136   25 %  |
|    | | | |                                                                                                                                                            |                  |                      |
|    | | | +---com.anritsu.pa3.application.pa3datastore.AppLogSessionWriter.writeDataKey(Pa3DataKey)                                                                    |    9,568   33 %  |    3,633,880   22 %  |
|    | | | | |                                                                                                                                                          |                  |                      |
|    | | | | +---com.anritsu.pa3.application.pa3datastore.AppLogSessionWriter.flushDataKeys()                                                                           |    9,568   33 %  |    3,633,880   22 %  |
|    | | | |   |                                                                                                                                                        |                  |                      |
|    | | | |   +---com.anritsu.pa3.application.pa3datastore.AppLogSessionWriter.addDataKeys(Collection)                                                                 |    9,568   33 %  |    3,633,880   22 %  |
|    | | | |     |                                                                                                                                                      |                  |                      |
|    | | | |     +---com.objectdb.jpa.EMImpl.commit()                                                                                                                   |    8,072   28 %  |    3,609,944   22 %  |
|    | | | |     |                                                                                                                                                      |                  |                      |
|    | | | |     +---com.objectdb.jpa.EMImpl.persist(Object)                                                                                                            |    1,496    5 %  |       23,936    0 %  |
|    | | | |                                                                                                                                                            |                  |                      |
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------+----------------------+
#2

ObjectDB allocates internal data structures for every persisted object, but uses weak references, so as soon as you release 

your own references to these entity objects they can be released by the GC.

Since all the persisted objects are in one large collection, aDataKeys, please check when this collection is released.

It is also recommended to use always enhanced classes.

If after releasing of aDataKeys and running the GC you still see that many ObjectDB objects are not released, please provide a heap dump.

ObjectDB Support
#3

Yes we know about WEAK REFERENCEs in ObjectDb to application entities and tried to remove all used objects after commit like shown below:

if ( m_EntityManager.isOpen() && !m_DataKeysCache.isEmpty() )
{
     m_EntityManager.getTransaction().begin();

      for ( Pa3DataKey dataKey : m_DataKeysCache )
      {
         m_EntityManager.persist( dataKey );
      }

      m_EntityManager.getTransaction().commit();

      m_DataKeysCache.clear();

      m_EntityManager.flush();
      m_EntityManager.clear();
}

When we completed import data to database we also using following code for flush all data to DB and release memory

m_EntityManager.flush();
m_EntityManager.clear();
m_EntityManager.close();

But memory leaks still exists till we forcing CLOSE DB using

m_EntityMgrFactory.close()

The main problem that we are not expecting to close DB after import data and would like to release acquired by ObjectDB memory after many commits and continue working with opened before database.

#4

To explore this issue further we need more information.

Please collect a heap dump (e.g. using VisualVM) and also search for nearest GC roots to relevant ObjectDB objects.

ObjectDB Support

Reply