Freitag, 24. September 2010

Java Virtual Machine Hotspot Compilation Investigation (sun 1.6)

Today I asked my first question on

Hi all,

imagine a (container-) application is creating multiple classloaders to host a couple of other/sub- applications.

There is a -say- root classloader for the container app. Each time a sub-application is loaded, the container creates a new classloader for this application.

Some sub-applications use the same classes, but they were not loaded by the container's classloader, so each sub-application (better: its classloader) loads the code for e.g. class A. Therefore permspace will be filled twice: once for sub-application #1 and once for sub-app #2.

What does this mean for sun's hot-spot optimization?
Will the same optimizations occur twice on class A, once for each class-loader?
Or, is there some "magic" built-in which avoids this? (Optimizations done once)
Somebody knows a link, were this is explained?

I am referring to a sun vm shipping with jdk 1.6

Here's the link:

Fortunately, someone answered my question :))

Short answer: Yes, optimization is carried out for each classloader separately.

One of the readers challenged me to do a showcase.

So I did. (Neeme this is all your fault ;)

You can find the eclipse project here:

  1. You need to add "-XX:+PrintCompilation" as virtual machine argument in the "Run..." dialog for this project
  2. Adjust the working directory to point to "bin" in your run setting
Here's a screenshot:

If you got things right you'll see output like this in the console view:

1 java.lang.String::hashCode (64 bytes)
2 java.lang.String::charAt (33 bytes)
3 java.lang.String::indexOf (166 bytes)
4 java.lang.String::indexOf (151 bytes)
5 java.util.Random::next (47 bytes)
6 java.util.concurrent.atomic.AtomicLong::get (5 bytes)
7 java.util.concurrent.atomic.AtomicLong::compareAndSet (13 bytes)
--- n sun.misc.Unsafe::compareAndSwapLong
8 java.lang.Math::random (16 bytes)
9 java.util.Random::nextDouble (24 bytes)
10 com.acme.Application::calculateIndex (33 bytes)
11 com.acme.Application::calculateIndex (33 bytes)
12 com.acme.Application::calculateIndex (33 bytes)
13 com.acme.Application::calculateIndex (33 bytes)
14 com.acme.Application::calculateIndex (33 bytes)

Each line is printed as result of compiling bytecode to native code. You can see that the code in "calculateIndex" is compiled over and over again. This is because the "Application" class is loaded by multiple instances of a "special" classloader (called "ApplicationClassloader"). These classloaders are children of the System classloader.
There is no parent-child relationship between any instances of "ApplicationClassloader".

This is the result if the "client" vm is used (the default at least for winXP 32-bit).
The result for the server vm looks a little different but in effect it's the same.

Here's a link to a forum post I found, which helps in deciphering the output:

I ran this on my notebook with Windows XP (32-bit) installed. I used jdk 1.6.0_21.

I treated compilation/optimization as the same thing here. Sorry for the imperfection. As a sidenote I want to mention that sun's jvm may compile the same code multiple times. Anyway, I think I got what I was looking for.

So Finally, I made my first blog-post today as well. That's two achievements in one day! Probably I should spend the rest of my day on facebook . . . lol . . . *never*

Have a nice day!

Keine Kommentare:

Kommentar veröffentlichen