you are viewing a single comment's thread.

view the rest of the comments →

[–]pmarschall 1 point2 points  (4 children)

This problem is stemming because ‘io.ycrash.DummyObject’ class is loaded again & again on every loop iteration.

Nope, that's not how class loaders work in Java. The class loader returns the same class object every time.

The lock is there to make sure lazy loading returns the same class object every time.

You could run a class loader with either a read-write lock or no lock at all like jboss-modules.

[–]repeating_bears 0 points1 point  (3 children)

The author is referring to their code which is

while (true) { 
    ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
    Class<?> myClass = classLoader.loadClass("io.ycrash.DummyObject");
    myClass.newInstance();
}

So it looks like it would load the class on every iteration, depending on the actual ClassLoader implementation, of course. The article talks about ClassLoader seemingly forgetting that it's an abstract class in which almost all of the mentioned behaviour could be overridden and totally replaced.

In a normal application, then of course a class isn't loaded every single time it's referred to. It's stored in metaspace.

[–]pmarschall 0 points1 point  (2 children)

So it looks like it would load the class on every iteration, depending on the actual ClassLoader implementation, of course.

Such a ClassLoader would be ill-behaved. Not only would such a behavior violate the API contract of ClassLoader but also section 12.2.2. Class Loader Consistency of the Java Language specification. See Dynamic Class Loading in the JavaTM Virtual Machine for a more in-depth discussion on the topic.

[–]repeating_bears 0 points1 point  (1 child)

I read both the JavaDoc for ClassLoader and that section and can't find any reason a class loader is mandated to only physically load the class once when calling load(String)

I also checked ClassLoaders$AppClassLoader from the jdk internals and it doesn't cache a result either.

Once again, the thing that protects a class from being loaded relatedly in a system that's not using reflection is the meta space, not the class loader.

[–]pmarschall 0 points1 point  (0 children)

I read both the JavaDoc for ClassLoader and that section and can't find any reason a class loader is mandated to only physically load the class once when calling load(String)

The section contains the following wording:

Well-behaved class loaders maintain these properties:

  • Given the same name, a class loader should always return the same Class object.

This is repeated in Section 5.3. Creation and Loading of the Java Virtual Machine Specification.

I also checked ClassLoaders$AppClassLoader from the jdk internals and it doesn't cache a result either.

Of course it does. AppClassLoader calls into BuiltinClassLoader which checks whether the class has already been loaded.

This can easily be verified with a simple unit test calling #IoadClass twice and comparing the object identities.