At 19:04 14.08.2003 -0400, Matt_Conway@... wrote:
>We have a embedded jython framework which runs each jython interpreter in
>its own threadgroup/thread. As a result, we get reasonable startup
>performance for each new interpreter, but still get some segregation
>between them. Each interpreter also has its own custom sys.classLoader and
>sys.packageManager to handle dynamic changes to the classpath independently
>for each interpreter. This is all working great, however, I recently ran
>into a memory exhaustion scenario, and after tracking down all my own
>leaks, I found that the architecture of the jython engine was also causing
>me some problems.
>Specifically, PyJavaClass has the member "private static InternalTables tbl
>" which seems to cache a mapping between java classes and their
>PyJavaClasses. This is causing me grief because the PyJavaClass holds on
>to a reference to its package manager, which is my custom package manager,
>which holds on to a large amount of data (basically all the packages and
>classes for the classpath for the interpreter, which can be very large as
>we have some giant classpaths), and thus memory can be exhausted pretty
>Is there an easy way to solve this? Should the tbl member instead of being
>static be like PySystemState which is thread dependent?
the Class -> PyJavaClass mapping should be globally unique.
python.options.internalTablesImpl = weak
makes the PyJavaClass entries collectible.
jython-dev-admin@... wrote on 08/14/2003 08:03:11 PM:
> python.options.internalTablesImpl = weak
> makes the PyJavaClass entries collectible.
Ok, I spoke too soon - this almost does the trick. The problem is that my
custom classloader does not get garbage collected because the
PyJavaClass.tbl only has the PyJavaClass as a Weak reference - the actual
Class (which refs the classoader) which is a key in that table never gets
Is there any reason the Class key couldn't be a weak reference too?
At 15:27 15.08.2003 -0400, Matt_Conway@... wrote:
>jython-dev-admin@... wrote on 08/14/2003 08:03:11 PM:
> > python.options.internalTablesImpl = weak
> > makes the PyJavaClass entries collectible.
>Ok, I spoke too soon - this almost does the trick. The problem is that my
>custom classloader does not get garbage collected because the
>PyJavaClass.tbl only has the PyJavaClass as a Weak reference - the actual
>Class (which refs the classoader) which is a key in that table never gets
no, there is code such that when PyJavaClass weak ref has become invalid,
the corresponding entry Class -> weak(PyJavaClass) will be removed.
The code is triggered on table access, or through
That means generally, that when the PyJavaClasses are collected then at some
point the classes will be removed from the table and then if they didn't live
outside the table, the classloader and the classes will be collected.
If you want to be sure that what is collectible has been collected at some
But if PyJavaClass intances or classes or classloaders are around outside
the table, they cannot be collected.
>Is there any reason the Class key couldn't be a weak reference too?
for the weak impl, in absolute terms, none. I presume I favored code reuse,
speed when I wrote that.
Now I think that weak ought to be the default, the problem is then
trashing, because the weak impl guarantees uniquess but not to keep the
PyJavaClass around as long as the class is around and across GCs. So the
PyJavaClass, if it's not kept alive outside the table, can need to be
recreated more than once, which can be costly.