This discussion is archived
1 Reply Latest reply: Jan 17, 2011 5:07 AM by 830554 RSS

classloading in scoped memory

830188 Newbie
Currently Being Moderated
Hello,

currently I am trying to figure out how classloading in scoped memory can be done.
I tried the following code which is executed by a RealtimeThread:
public void run() {
// allocation context is: heap

final ScopedMemory scopeA = new LTMemory(50000);
final ScopedMemory scopeB = new LTMemory(50000);

// RtjTestClassloader simply loads a class from a .class-file that
// exists somewhere in the filesystem
final ClassLoader cloader = new RtjTestClassloader();

try {
    // loading a class in scoped memory fails if no class was loaded
    // using that classloader before entering the scope
    Class<?> c = cloader.loadClass(OTHER_CLASS);
} catch (ClassNotFoundException e) { 
    System.exit(1);
} 

scopeA.enter(new Runnable() { 
    public void run() {
        try {
            System.err.println("scopeA entered");
            Class<?> clazz = cloader.loadClass(CLASS);
            TestClass tc = (TestClass)clazz.newInstance();
            System.err.println("scopeA memory consumed: " + scopeA.memoryConsumed());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
});

scopeB.enter(new Runnable() {
    public void run() {
        try {
            System.err.println("scopeB entered");
            System.err.println("scopeA memory consumed: " + scopeA.memoryConsumed());
            Class<?> clazz = cloader.loadClass(CLASS);
            TestClass tc = (TestClass)clazz.newInstance();
            System.err.println("scopeB memory consumed: " + scopeB.memoryConsumed());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
});
}
the output is:
scopeA entered
scopeA memory consumed: 16240
scopeB entered
scopeA memory consumed: 0
scopeB memory consumed: 1896

If the Class object would be allocated in scopeA it would not be possible to
use that Class object in scopeB since classes can only be loaded once per
classloader (the high memory consumption of scopeA is probably because of
opening a file). That implies that classes must be allocated on the heap or in
immortal memory. Is that the case in the Sun Java RTS?

Furthermore the above code fails when run in TimeSys JVM. Trying to load the
class in scopeA causes an IllegalAsignmentError when defineClass(...) is called.
I suspect that is due to the storing of the reference to the loaded class for
later use. Which would again imply that TimeSys really allocates memory for
Class objects inside the scope.
The same Error happened when I tried to load a class with a classloader that was
instanciated in scoped memory (using Sun Java RTS).

Another interesting notice is that the loading of the class in scopeA only works
if the classloader was used to load a class in heap or immortal memory before
entering the scope.

What happens when a class is being loaded and scopes are involved? Is there an
approach that should be used when having multiple classloaders and scopes?
And is there anything in the RTSJ Spec on that? I wasn't able to find anything.

Thank you,
Matthias

Edited by: user13696541 on 11.01.2011 13:46
  • 1. Re: classloading in scoped memory
    830554 Newbie
    Currently Being Moderated
    Hello,

    I have to push this topic, because it addresses a common question about the scenario of (user-defined) class loading in Real-Time Java, especially when mixed up with Scope usage.
    I'm wondering if user-defined Class Loading has been addressed yet in the RTSJ?
    Because of the absence of any statement about it within the RTSJ specification (or any of the well-known books about RTSJ),
    we assumed the problem is implementation-specific.

    Therefore we decided to do some tests, which Matthias has presented here in his previous post.

    The cited code above exemplifies a simple class loading scenario executed by a Real-Time JVM:

    A RealTimeThread enters a scope A and uses a Class Loader instance "cloader" residing on the Heap in order to load a certain class "CLASS" within that scope.
    On success, I would expect that the entire control structures defining the class "CLASS" are situated within the scope A.
    As you can see the program output, after the class loading procedure Class<?> clazz = cloader.loadClass(CLASS),
    there are about 16 Kbytes of scope A in use (e.g. something happened on class loading within that scope).

    Afterwards, the RT-Thread leaves the scope A, and according to it's memory usage (= 0) the latter seems to be already freed (e.g. no active threads therein anymore).
    This would impose, that the definition structures (or parts of them) of the class "CLASS" that were placed within the scope A are lost now, wouldn't it?

    However, this seems not to be the case.
    The RT-Thread enters a new scope B and tries to reload the same class "CLASS" with the same "cloader" instance residing on the heap.
    I would expect, that the "CLASS" is either redefined in some way within scope B, or that the JVM throws a kind of error since the definition for "CLASS" has been already lost with scope A.
    Nevertheless, "cloader" simply returns a valid Class object for the "CLASS" which can be further instantiated and used without any problems.
    But, the memory usage of scope B is much lower (= 1896 bytes) than that of scope A after defining the "CLASS".

    This raises a common question:

    1. Where does the JRTS JVM place Class Objects of newly defined classes (in terms of the Java "Class" object and the corresponding JVM-internal definition structures)?
    a) The current allocation scope of the Thread actually defining a class?
    b) Some other scope (e.g. a class cache) ?

    2. What happens in the scenario above? What is allocated on class loading within scope A, and how is it possible to have a valid class definition of "CLASS" since scope A has been freed?


    We've tried another use case, having a separate class loader object "rtcl" instantiated within a scope C, which again loads the class "CLASS" within the same scope C:
    mc.enter(new Runnable() {
                    public void run() {
                        try {
                            ClassLoader rtcl = new RtjTestClassloader();
                            Class c = rtcl.loadClass(CLASS3);
                            TestClass cl3 = (TestClass) c.newInstance();
                        } catch (Exception e) { e.printStackTrace(); }
                    }
                });
    
    ------ 
    Output:
    
    Exception in thread "RealtimeThread-0" javax.realtime.IllegalAssignmentError
         at java.util.HashMap$Entry.<init>(HashMap.java:730)
         at java.util.HashMap.addEntry(HashMap.java:797)
         at java.util.HashMap.put(HashMap.java:431)
         at java.util.HashSet.add(HashSet.java:194)
         at java.lang.ClassLoader.checkPackageAccess(ClassLoader.java:346)
         at java.lang.ClassLoader.defineClass1(Native Method)
         at java.lang.ClassLoader.defineClass(ClassLoader.java:630)
         at java.lang.ClassLoader.defineClass(ClassLoader.java:475)
         at rtjtests.classloader.RtjTestClassloader.loadClass(RtjTestClassloader.java:35)
         at rtjtests.classloader.ClassLoadingInScopeTest$3.run(ClassLoadingInScopeTest.java:138)
         at javax.realtime.MemoryArea.enter0(Native Method)
         at javax.realtime.MemoryArea.enter(MemoryArea.java:190)
         at javax.realtime.ScopedMemory.enter(ScopedMemory.java:191)
         at rtjtests.classloader.ClassLoadingInScopeTest.run(ClassLoadingInScopeTest.java:114)
    3. If I interpret the programs output right,
    - Class Loaders in JRTS seem to use traditional java.util.HashMap objects for storing references to their loaded classes
    - The class loading procedure really placed something on the scope (i.e. the class's Class object?)
    - For some reasons the class loader cannot store a reference to that object on the scope within its HashMap.

    Could anyone give us a short explaination of the internal representation of class objects and their corresponding class loaders?
    What are the reasons the RT-JVM behavior described above during our tests?

    Is there any intended or standardized way for the usage of extended class loading within RTSJ scopes?

    We would appreciate any help !

    Sincerely,
    Vladimir

    Edited by: vladimir.nikolov on Jan 17, 2011 5:05 AM

    Edited by: vladimir.nikolov on Jan 17, 2011 5:06 AM

    Edited by: vladimir.nikolov on Jan 17, 2011 5:07 AM

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points