In the past few days, several users reported symptoms of memory leaks in jcc-PyLucene. After a bit of sleuthing, I found two leaks:

   1. A reference to a Python Java wrapper was leaked whenever an inherited
      method was called on the Java object from Python (in callSuper).
      Fixing this one was trivial and is checked in to the svn trunk.

      I don't know if this fixes the cases reported but it certainly has
      a major impact. For instance, any time searcher.search(query) is
      called, the searcher is leaked (!).

      To verify this, run:
      > python test/test_PyLucene.py 
Test_PyLuceneWithFSStore.test_searchDocuments -loop
      Without the fix, after a short while, the VM runs out of memory.
      With the fix, it seems to be running forever (and speed remains more or
      less constant)

   2. A "deadly embrace" between a Python extension instance and its Java
      parent instance is currently preventing Python extention instances
      and their Java parent from ever being freed. The Python extension
      instance is holding a reference to the Java parent instance and the
      Java parent instance is holding a reference to the Python extension
      instance.
      Without some explicit intervention, this cross-VM cycle can't be
      broken. I'm currently thinking of making it possible to call finalize()
      on these objects manually to break the cycle. I'm also thinking of
      adding a GC thread to the process that would garbage collect the
      extension instances with no more than two counted python refs. This
      thread, combined with weak global refs on the JNI side could make
      collecting these Python extension instances semi-automatic. Needless
      to say, I don't like this idea too much and I'm trying to find another
      less complicated way. In the meantime, I think I'm going to be adding
      support for the manual way via finalize() shortly.

      This leak (still in svn trunk), is not normally that bad, as Python
      extension instances are rarer (than the earlier leak) and leaking them
      is, normally, not as deadly. Still, there are cases where it is bad as
      when implementing a Python extension for Directory and its sibling
      classes.
      To see for yourself, try running test/test_PythonDirectory.py in a
      loop. This leak is a problem in the current Chandler release, for
      example, where such a Python extension is used.

      More on this leak in the next few days.


In order to debug these leaks, I improved env._dumpRefs() a bit by adding some keywords to it.

_dumpRefs() now can be called in three ways:

   - _dumpRefs(): returns a list of tuples (system hash id, ref count)
     these are useful for quickly getting an idea of how many global Java
     referenced objects there are at the moment (these objects are not GC'ed
     by Java until removed from the refs table)

   - _dumpRefs(classes=True): returns a dict of { className: instance count }
     to get an idea about how many instances of various classes are being
     thus kept from being GC'ed by Java

   - _dumpRefs(values=True): returns a list of tuples (value string, ref
     count) to get an idea of what the values look like. This is to be used
     with caution a printing out Java values can be expensive.

It would be interesting to see if the people who recently reported memory leak symptoms on this list could try the current trunk and report if that solves their problem or at least, improves on it. If you are re-building PyLucene from the trunk to try this out, be sure to completely rebuild jcc first (the fix is there).

Thank you for your patience !

Andi..
_______________________________________________
pylucene-dev mailing list
[email protected]
http://lists.osafoundation.org/mailman/listinfo/pylucene-dev

Reply via email to