On 10/31/06, Pavel Pervov <[EMAIL PROTECTED]> wrote:
Ignatenko vs Gagnon proposal checklist follows. :)


> In accordance with Section 2.17.8 of the JVM spec, class unloading (and
> its related native resource cleanup) can only happen when the class
> loader instance becomes unreachable.  For this to happen, we put in
> place the following things:

1- Each class loader is represented by some VM internal structure.
> [We'll call it the "class loader structure"].


This is true.



> 2- Each class loader internal structure, except (optionally) the
> bootstrap class loader, maintains a weak reference to an object
> instance of class ClassLoader (or some subclass).  The Java instance
> has some opaque pointer back to the internal VM structure.   The Java
> instance is usually created before the internal VM structure.  The
> instance constructor is usually in charge of creating the internal VM
> structure.  [We'll call it the "class loader instance"]


This is true.



> 3- Each class loader instance maintains a collection of loaded classes.
> A class/interface is never removed from this collection.  This
> collection maintains "hard" (i.e. "not weak") references to
> classes/interfaces.


This is true.



> 4- [Informative] A class loader instance is also most likely to maintain
> a collection of classes for which it has "initiated" class loading.
> This collection should use hard references (as weak references won't
> lead to earlier class loading).


This is not true. Look for the thread "[drlvm] Non-bug difference
HARMONY-1688?", where Eugene Ostrovsky desribed initiating loaders in
details with links to specification.


> 5- Each class loader instance maintains a hard reference to its parent
> class loader.  This reference is (optionally) null if the parent is the
> bootstrap class loader.


This is true. This is actually a part of delegation framework.



> 6- Each j.l.Class instance maintains a hard reference to the class
> loader instance of the class loader that has loaded it.  [This is not
> the "initiating" loaders, but really the "loading" loader].


This is true. AFAIU, this class loader is called "defining" loader for a
class.



> 7- Each class loader structure maintains a set of boolean flags, one
> flag per "non-nursery" garbage collected area (even when thread-local
> heaps are used).  The flag is set when an instance of a class loaded by
> this class leader is moved into the related GC-area.  The flag is unset
> when the GC-area is emptied, or (optionally) when it can be determined
> that no instance of a class loaded by this class loader remains in the
> GC-area.  This is best implemented as follows: a) use an unconditional
> write of "true" in the flag every time an object is moved into the
> GC-area by the garbage collector, b) unset the related flag in "all"
> class loader structures just before collecting a GC-area, then setting
> the flag back when an object survives in the area.


Requires identification of object' class type during GC. Will most
probably degrade GC performance.

Yes, this is also my concern.

Thanks,
xiaofeng

> 8- Each method invocation frame maintains a hard reference to either its
> surrounding instance (in case of instance methods, i.e. (invokevirtual,
> invokeinterface, and invokespecial) or its surrounding class
> (invokestatic).  This is already required for synchronized methods
> (it's not a good idea to allow the instance to be collected before the
> end of a synchronized instance method call; yep, learned the hard way
> in SableVM...)  So, the "overhead" is quite minimal.  The importance of
> this is in the correctness of not letting a class loader to die while a
> static/instance method of a class loaded by it is still active, leading
> to premature release of native resources (such as jitted code, etc.).


Not generally true for optimizing JITs. "This" (or "class") can be omitted
from enumeration if it is not used anywhere in the code. Generally, this
technique reduces number of registers used in the code ("register pressure"
they call it :)).



> 9- A little magic is required to prevent premature collection of a class
> loader instance and its loaded j.l.Class instances (see [3-] above), as
> object instances do not maintain a hard reference to their j.l.Class
> instance, yet we want to preserve the correctness of Object.getClass().
>
> So, the simplest approach is to maintain a hard reference in a class
> loader structure to its class loader instance (in addition to the weak
> reference in [2-] above).  This reference is kept always set (thus
> preventing collection of the class loader instance), except when *all*
> the following conditions are met:
> a) All nurseries are empty.
> b) All GC-area flags are unset.


This requires more involvment of a GC in unloading process and affects GC
code more. In DRLVM, GC is designed to be a replaceable component. Moreover,
we already have 3 different working GCs and MMTk on the way. So, including
GC into the design is not a good idea for DRLVM.


<SNIP>

In addition,I highly recommend using the approach proposed in Chapter 3
> of http://sablevm.org/people/egagnon/gagnon-phd.pdf for managing
> class-loader related memory.  It has many advantages:


It is also true. Per class loader memory allocation is already used for part
of data allocated for this class loader. Look in HARMONY-2000 which brings
per-class loader pools to the extent.

<SNIP>

--
Pavel Pervov,
Intel Enterprise Solutions Software Division


Reply via email to