Uploaded image for project: 'Causeway'
  1. Causeway
  2. CAUSEWAY-1134

DN connections leak due to non-closed queries (?!)

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Major
    • Resolution: Fixed
    • core-1.8.0
    • tidy-up
    • Core
    • None

    Description

      My application failed twice with OutOfMemoryError in heap space so I've dumped a .hprof of its memory (jmap -dump:format=b,file=some-file.hprof) and analyzed it with Eclipse MAT (https://eclipse.org/mat/).
      It appears that there are many org.datanucleus.store.rdbms.query.JDOQLQuery$2 objects.
      JDOQLQuery$2 appears to be ManagedConnectionResourceListener ( https://github.com/datanucleus/datanucleus-rdbms/blob/651c77ff3b2af76ada97d14b537cd41fb0524a0c/src/java/org/datanucleus/store/rdbms/query/JDOQLQuery.java#L740).
      The listener is removed only when org.datanucleus.store.query.AbstractQueryResult#close() method is called.

      org.apache.isis.objectstore.jdo.datanucleus.persistence.queries.PersistenceQueryFindAllInstancesProcessor#process() does:

      final List<?> pojos = (List<?>) jdoQuery.execute();
      return loadAdapters(specification, pojos);
      

      So it consumes the result and returns ObjectAdapter for each pojo but it doesn't close the Query.
      AFAIK open-session-in-view pattern is not used in Isis so the resources should be closed explicitly after usage.
      A simple solution is to try/finally this code and close the query but I may miss some detail here.

      Related: recently I've profiled the application with Yourkit and it showed that DomainObjectContainer#allMatches() method is slow in one of the use cases. Some quick investigation showed that DomainObjectContainer delegates the work to org.apache.isis.objectstore.jdo.datanucleus.persistence.queries.PersistenceQueryProcessor#process(). It loads the POJOs from the DB, then wraps them in ObjectAdapters, and finally org.apache.isis.core.metamodel.services.container.DomainObjectContainerDefault#allMatches(org.apache.isis.applib.query.Query<T>) unwraps them back to POJOs.
      Why this is done?
      This solves the issue of "consume the QueryResult before closing it" for the memory leak issue but it also adds to the processing time.

      Attachments

        Activity

          People

            danhaywood Daniel Keir Haywood
            mgrigorov Martin Tzvetanov Grigorov
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: