harmony-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Pavel Pervov" <pmcfi...@gmail.com>
Subject Re: The way to increase the SPECjAppServer2004 score by 20%
Date Tue, 30 Oct 2007 12:33:31 GMT
Eugene, Sergey,

I've written the test (attached to HARMONY-4965: test.java) that illustrates
that RI does not cache class (record a class in "initiating" class loader)
if the direct call to ClassLoader.loadClass is done.

WBR,
    Pavel.
On 10/26/07, Evgueni Brevnov <evgueni.brevnov@gmail.com> wrote:
>
> Now it's clear why RI doesn't call parent's loadClass() directly but
> uses internal chain instead. It does so to distinguish between
> initiating class loader and other loaders. Don't you think so?
>
> Hmm...such behaviour doesn't seem to be strictly alligned with the
> spec but RI does so.....should we do the same? I think yes.
>
> Thanks
> Evgueni
>
> On 10/25/07, Sergey Dmitriev <sergey.v.dmitriev@gmail.com> wrote:
> > Evgueni
> >
> > as for the:
> >
> > > 2) Every class loader in the calling chain is marked as initiated
> > > class loader for class hi since findLoadedClass() returns non null
> > > value.
> >
> > I just have checked on RI: after we'have called Class.forName("hi",
> > CL3), if we do not explicitly call Class.forName("hi", CL2) the
> > CL2.findLoadedClass() returns false. So not every class loader from
> > the chain becomes the "initiated" one. Here is the output of slightly
> > modified classloadertest2.java (commented out the explicit loading of
> > "hi" via CL2):
> >
> > mycl1.parent = sun.misc.Launcher$AppClassLoader@601bb1
> > mycl2.parent = [MyClassLoader [dir:my]]
> > mycl3.parent = [MyClassLoader [dir:X2]]
> > [MyClassLoader [dir:X3]].loadClass(hi) enter...
> > [MyClassLoader [dir:my]].findClass(hi) enter...
> > [MyClassLoader [dir:my]].loadClassData(hi) enter...
> > [MyClassLoader [dir:my]].loadClassData(hi) exit. out = [B@1e5e2c3
> > [MyClassLoader [dir:my]].findClass(hi) exit. out = [B@1e5e2c3
> > [MyClassLoader [dir:my]].loadClass(java.lang.Object) enter...
> > [MyClassLoader [dir:my]].loadClass(java.lang.Object) exit. out = class
> > java.lang.Object
> > [MyClassLoader [dir:X3]].loadClass(hi) exit. out = class hi
> > Class.forName("hi", true, mycl3) = [class hi]
> > mycl1.findLoadedClass(hi) = [class hi]
> > mycl2.findLoadedClass(hi) = [null]
> > mycl3.findLoadedClass(hi) = [class hi]
> >
> > Next thing I would note, I just looked to "The JavaTM Virtual Machine
> > Specification" and realized that [CL3.findLoadedClass(hi) != hi.class]
> > behaviour is what we have to fix because CL3 is the "initiating one";
> > but the behaviour of [Class.forName("hi", CL3); Class.forName("hi",
> > CL2) -> CL2.findLoadedClass("hi") == hi.class] is optional thing I
> > would say, this is not specified clearly. And actually the last thing
> > is desired, meaning consequent calls of CL.loadClass("class") should
> > not run though the whole chain every time even if the "class" was
> > loaded before but by the different classloader.
> >
> >
> > Thanks
> > Sergey
> >
> >
> > On 10/25/07, Evgueni Brevnov <evgueni.brevnov@gmail.com> wrote:
> > > This test shows two things:
> > >
> > > 1) SUN doesn't strictly follow the spec since it doesn't call
> > > loadClass() method of the parent class loader but uses alternative
> > > call chain instead.
> > >
> > > 2) Every class loader in the calling chain is marked as initiated
> > > class loader for class hi since findLoadedClass() returns non null
> > > value.
> > >
> > > I believe if you change class loader's parent on the fly it will not
> > > have any effect on already loaded classes. So it should be legal (and
> > > compatible with SUN) to cache classes.
> > >
> > > Thanks
> > > Evgueni
> > >
> > >
> > >
> > > On 10/24/07, Sergey Dmitriev <sergey.v.dmitriev@gmail.com> wrote:
> > > > Hello
> > > >
> > > > sorry for such a delay. Here what I've got with my experiments.
> Please
> > > > refer to  classloadertest2.java attached to JIRA.
> > > >
> > > > Talking about the Pavel's case: CL1 <- CL2 <- CL3, loading via CL3
> > > > then loading via CL2.
> > > >
> > > > SUN JDK 6:
> > > > mycl1.parent = sun.misc.Launcher$AppClassLoader@601bb1
> > > > mycl2.parent = [MyClassLoader [dir:my]]
> > > > mycl3.parent = [MyClassLoader [dir:X2]]
> > > > [MyClassLoader [dir:X3]].loadClass(hi) enter...
> > > > [MyClassLoader [dir:my]].findClass(hi) enter...
> > > > [MyClassLoader [dir:my]].loadClassData(hi) enter...
> > > > [MyClassLoader [dir:my]].loadClassData(hi) exit. out = [B@1e5e2c3
> > > > [MyClassLoader [dir:my]].findClass(hi) exit. out = [B@1e5e2c3
> > > > [MyClassLoader [dir:my]].loadClass(java.lang.Object) enter...
> > > > [MyClassLoader [dir:my]].loadClass(java.lang.Object) exit. out =
> class
> > > > java.lang.Object
> > > > [MyClassLoader [dir:X3]].loadClass(hi) exit. out = class hi
> > > > Class.forName("hi", true, mycl3) = [class hi]
> > > > [MyClassLoader [dir:X2]].loadClass(hi) enter...
> > > > [MyClassLoader [dir:X2]].loadClass(hi) exit. out = class hi
> > > > Class.forName("hi", true, mycl2) = [class hi]
> > > > mycl1.findLoadedClass(hi) = [class hi]
> > > > mycl2.findLoadedClass(hi) = [class hi]
> > > > mycl3.findLoadedClass(hi) = [class hi]
> > > >
> > > > HARMONY:
> > > > mycl1.parent = java.lang.ClassLoader$SystemClassLoader@1089e19e
> > > > mycl2.parent = [MyClassLoader [dir:my]]
> > > > mycl3.parent = [MyClassLoader [dir:X2]]
> > > > [MyClassLoader [dir:X3]].loadClass(hi) enter...
> > > > [MyClassLoader [dir:X2]].loadClass(hi) enter...
> > > > [MyClassLoader [dir:my]].loadClass(hi) enter...
> > > > [MyClassLoader [dir:my]].findClass(hi) enter...
> > > > [MyClassLoader [dir:my]].loadClassData(hi) enter...
> > > > [MyClassLoader [dir:my]].loadClassData(hi) exit. out = [B@108d9a98
> > > > [MyClassLoader [dir:my]].findClass(hi) exit. out = [B@108d9a98
> > > > [MyClassLoader [dir:my]].loadClass(java.lang.Object) enter...
> > > > [MyClassLoader [dir:my]].loadClass(java.lang.Object) exit. out =
> class
> > > > java.lang.Object
> > > > [MyClassLoader [dir:my]].loadClass(hi) exit. out = class hi
> > > > [MyClassLoader [dir:X2]].loadClass(hi) exit. out = class hi
> > > > [MyClassLoader [dir:X3]].loadClass(hi) exit. out = class hi
> > > > Class.forName("hi", true, mycl3) = [class hi]
> > > > [MyClassLoader [dir:X2]].loadClass(hi) enter...
> > > > [MyClassLoader [dir:my]].loadClass(hi) enter...
> > > > [MyClassLoader [dir:my]].loadClass(hi) exit. out = class hi
> > > > [MyClassLoader [dir:X2]].loadClass(hi) exit. out = class hi
> > > > Class.forName("hi", true, mycl2) = [class hi]
> > > > mycl1.findLoadedClass(hi) = [class hi]
> > > > mycl2.findLoadedClass(hi) = [null]
> > > > mycl3.findLoadedClass(hi) = [null]
> > > >
> > > > First thing that one can catch: in case of SUN we don't touch the
> CL2
> > > > at all during the loading via CL3. Interesting.
> > > >
> > > > And during the loading via CL2 SUN does not touch the CL1.
> > > >
> > > >
> > > > Thanks
> > > > Sergey
> > > >
> > > > On 10/23/07, Evgueni Brevnov <evgueni.brevnov@gmail.com> wrote:
> > > > > Pavel,
> > > > >
> > > > > I don't know exact answer to you question :-(, sorry, I hope
> Dmitry
> > > > > will provide such information soon :-)
> > > > >
> > > > > I have two notes:
> > > > >
> > > > > 1) I believe the spec requires to return the same class each time
> > > > > since a pair <ClassLoader, ClassName> must uniquely identify
java
> > > > > class. So in you example from the first letter CL2 should always
> > > > > return the same class.
> > > > >
> > > > > 2) Regarding "initiating" class loader notion. My understanding is
> > > > > that each class loader in the hierarhy chain up to defining one
> should
> > > > > be marked as initiating class loader. At least this is written
> in  [1]
> > > > >
> > > > > [1] "Inside the Jva2 Virtual Machine" by Bill Venners.
> > > > >
> > > > > Thanks
> > > > > Evgueni
> > > > > On 10/23/07, Pavel Pervov <pmcfirst@gmail.com> wrote:
> > > > > > Evgueni,
> > > > > >
> > > > > > 1) Our own URLClassLoader overrides ClassLoader.loadClassmethod,
so the
> > > > > > idea of adding such registry to base class will not work from
> the start.
> > > > > >
> > > > > > 2) The question in my previous letter is not answered. If the
> answer is
> > > > > > positive, then adding the registry of "initiated" classes to
> URLClassLoader
> > > > > > (which AFAIU will cover the issue described by Sergey) still
> requires solid
> > > > > > algorithm to distinguish the class loader which was initially
> asked to load
> > > > > > a class from the one, which resides in the middle of delegation
> chain.
> > > > > >
> > > > > > I'm not against caching, I just see problems I do not know how
> to solve.
> > > > > >
> > > > > > WBR,
> > > > > >    Pavel.
> > > > > >
> > > > > > P.S. BTW, we have the registry of "initiated" classes but it
is
> only
> > > > > > appended on class resolutions.
> > > > > > On 10/23/07, Evgueni Brevnov <evgueni.brevnov@gmail.com>
wrote:
> > > > > > >
> > > > > > > Pavel,
> > > > > > >
> > > > > > > As you pointed out to change delegation model user must
> override
> > > > > > > ClassLoader.loadClass() method. By doing so user can specify
> any
> > > > > > > search order he only want and doesn't depend on caching
> capabilities
> > > > > > > provided by java.lang.ClassLoader. If user uses default
> implementation
> > > > > > > of ClassLoader.loadClass() method then it should be safe
to
> use cache.
> > > > > > > What do you think?
> > > > > > >
> > > > > > > Thanks
> > > > > > > Evgueni
> > > > > > >
> > > > > > > On 10/23/07, Pavel Pervov <pmcfirst@gmail.com> wrote:
> > > > > > > > Evgueni,
> > > > > > > >
> > > > > > > > ClassLoader.loadClass is not final. One can overload
this
> and build any
> > > > > > > > delegation model his or her application requires.
So, -1
> here.
> > > > > > > >
> > > > > > > > It would be good to answer the following case before
> considering class
> > > > > > > > caching.
> > > > > > > >
> > > > > > > > Assume, we have delegation of three class loaders:
> CL1<-CL2<-CL3.
> > > > > > > > Assume, class Foo is only available from CL1.
> > > > > > > >
> > > > > > > > We call to CL3.loadClass("Foo"). The call chain will
look
> like
> > > > > > > > CL3.loadClass->CL2.loadClass->CL1.loadClass.
As far as we
> know, the
> > > > > > > second
> > > > > > > > and subsequent calls to CL3.loadClass("Foo") will
not call
> to
> > > > > > > > CL2.loadClass("Foo")
> > > > > > > > but return "cached" copy from CL3 on RI (as described
by
> Sergey).
> > > > > > > >
> > > > > > > > But it would be really interesting to know if the
call to
> CL2.loadClasswill
> > > > > > > > result in call chain CL2.loadClass->CL1.loadClass.
> > > > > > > >
> > > > > > > > If this is true, my initial idea that it is only allowed
to
> register the
> > > > > > > > class in "initiating" and "defining" loaders is also
true.
> And I have no
> > > > > > > > solid solution to determining "initiating" class loader.
> > > > > > > >
> > > > > > > > Otherwise, it is ok to create the cache in URLClassLoader
as
> Sergey
> > > > > > > > initially suggested.
> > > > > > > >
> > > > > > > > Pavel.
> > > > > > > >
> > > > > > > > On 10/23/07, Evgueni Brevnov <evgueni.brevnov@gmail.com>
> wrote:
> > > > > > > > >
> > > > > > > > > Pavel,
> > > > > > > > >
> > > > > > > > > I think its not common situation when parent
class loader
> is changed
> > > > > > > > > at runtime. To be honest I don't know how it's
possible
> since parent
> > > > > > > > > class loader is kept in private field. Anyway,
can we
> somehow detect
> > > > > > > > > such situation and switch to normal scheme or
discard
> cached classes
> > > > > > > > > upon switching parent class loader.
> > > > > > > > >
> > > > > > > > > Thanks
> > > > > > > > > Evgueni
> > > > > > > > >
> > > > > > > > > On 10/22/07, Pavel Pervov <pmcfirst@gmail.com>
wrote:
> > > > > > > > > > Looking at the Java Virtual Machine Specification
there
> are two
> > > > > > > terms:
> > > > > > > > > > initiating loader and defining loader.
> > > > > > > > > >
> > > > > > > > > > Initiating loader is the class loader which
was first
> asked to load
> > > > > > > > > class in
> > > > > > > > > > delegation chain (CL2 in your example).
> > > > > > > > > >
> > > > > > > > > > Defining loader is the class loader which
has found
> bytes for class
> > > > > > > > > > definition and called to JNI->DefineClass.
> > > > > > > > > >
> > > > > > > > > > Lets review the following delegation model.
> > > > > > > > > >
> > > > > > > > > > CL1<-CL2<-CL3
> > > > > > > > > >
> > > > > > > > > > CL4<-CL2<-CL5
> > > > > > > > > >
> > > > > > > > > > There is nothing wrong with CL2: its delegation
model
> simply assumes
> > > > > > > > > > switching delegation parent depending on
some external
> property.
> > > > > > > > > >
> > > > > > > > > > Different versions of class Foo are available
from CL1
> and CL4. Now,
> > > > > > > we
> > > > > > > > > do
> > > > > > > > > > something like CL3.loadClass("Foo") and
CL5.loadClass
> ("Foo").
> > > > > > > > > > If CL2 will cache the class Foo, then the
call to CL5
> will return
> > > > > > > wrong
> > > > > > > > > > result.
> > > > > > > > > >
> > > > > > > > > > So the caching is possible, but it is only
allowed to
> register class
> > > > > > > in
> > > > > > > > > > initiating loader and in defining loader.
Otherwise, you
> may have
> > > > > > > wrong
> > > > > > > > > > classes returned to your application.
> > > > > > > > > >
> > > > > > > > > > Determining defining loader is simple. Can
you suggest
> some working
> > > > > > > idea
> > > > > > > > > on
> > > > > > > > > > how to determine initiating loader for a
class?
> > > > > > > > > >
> > > > > > > > > > WBR,
> > > > > > > > > >    Pavel.
> > > > > > > > > >
> > > > > > > > > > On 10/22/07, Sergey Dmitriev <
> sergey.v.dmitriev@gmail.com> wrote:
> > > > > > > > > > >
> > > > > > > > > > > Hello
> > > > > > > > > > >
> > > > > > > > > > > This letter is actually about HARMONY-4965,
I just
> changed a
> > > > > > > little
> > > > > > > > > > > bit a subject. :)
> > > > > > > > > > >
> > > > > > > > > > > During my play with SPECjAppServer2004
on OC4J I've
> found out that
> > > > > > > we
> > > > > > > > > > > have a way to optimize the class loader.
Or in other
> words
> > > > > > > currently
> > > > > > > > > > >
> > > > > > > > > > > Lets say we have class loaders CL1
and CL2, and
> CL2.getParent() ==
> > > > > > > > > > > CL1. And lets say we have a class C
which is loaded by
> the CL1
> > > > > > > (the
> > > > > > > > > > > parent one). And then we try to load
class via the
> class loader
> > > > > > > CL2:
> > > > > > > > > > > of course CL2 first of all tries to
load it via its
> parent CL1 and
> > > > > > > > > > > succeed in it. When we try to load
class C via CL2
> again we will
> > > > > > > have
> > > > > > > > > > > the same chain of calls: CL2 ->
CL1. But if CL2 have
> support of
> > > > > > > > > > > caching of classes loaded by not itself
- the chain
> can become
> > > > > > > much
> > > > > > > > > > > shorter - it could end at CL2.findFinishedClass().
> > > > > > > > > > >
> > > > > > > > > > > For example RI behaves like this. See
JIRA's demo.
> > > > > > > > > > >
> > > > > > > > > > > Back to the SPECjAppServer2004 @ OC4J.
In this case we
> have a
> > > > > > > deeper
> > > > > > > > > > > chain: we have a concrete class which
is been searched
> so deep
> > > > > > > that we
> > > > > > > > > > > looking for this class in boot strap
class path. And
> this is what
> > > > > > > we
> > > > > > > > > > > have in steady state of the benchmark.
Don't you think
> it is
> > > > > > > useless?
> > > > > > > > > > > :)
> > > > > > > > > > >
> > > > > > > > > > > Talking about numbers: my measurements
show that we
> can take up to
> > > > > > > 20%
> > > > > > > > > > > of burst having this bug fixed. Could
some competent
> guy take a
> > > > > > > look
> > > > > > > > > > > into this?
> > > > > > > > > > >
> > > > > > > > > > >
> > > > > > > > > > > Thanks
> > > > > > > > > > > Sergey
> > > > > > > > > > >
> > > > > > > > > >
> > > > > > > > > >
> > > > > > > > > >
> > > > > > > > > > --
> > > > > > > > > > Pavel Pervov,
> > > > > > > > > > Intel Enterprise Solutions Software Division
> > > > > > > > > >
> > > > > > > > >
> > > > > > > >
> > > > > > > >
> > > > > > > >
> > > > > > > > --
> > > > > > > > Pavel Pervov,
> > > > > > > > Intel Enterprise Solutions Software Division
> > > > > > > >
> > > > > > >
> > > > > >
> > > > > >
> > > > > >
> > > > > > --
> > > > > > Pavel Pervov,
> > > > > > Intel Enterprise Solutions Software Division
> > > > > >
> > > > >
> > > >
> > >
> >
>



-- 
Pavel Pervov,
Intel Enterprise Solutions Software Division

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message