Java Class Loading: InstanceKlass and Class Object Relationship

I always thought Class.forName("com.example.MyClass") just "loads a class." Turns out I had no idea what was actually happening. Went down a rabbit hole this week into how Java reflection works under the hood. Here is what I found: When the JVM loads a class, it creates two separate things: An InstanceKlass, a C++ struct in Metaspace. This is the JVM's actual representation of your class. Method table, field table, bytecode, runtime constant pool, all of it lives here. The execution engine works directly off this. A Class<?> object on the heap. This is what your Java code sees. It just holds a pointer back to the InstanceKlass. So every time you call getDeclaredMethods() or getField(), Java is doing this: Class<?> on heap -> klass pointer -> InstanceKlass in Metaspace That boundary crossing, plus access checks, is exactly why reflection has overhead. One more thing that surprised me: the String intern pool is not in Metaspace. It is a native C++ hash table called StringTable inside HotSpot, lives on the heap, uses weak references so unused strings get collected. Completely global across the JVM process. Most Java developers never look at this layer. Once you do, a lot of things that felt like magic start making sense. Going to keep writing about JVM internals. What part of the JVM caught you off guard when you first looked deeper? #Java #JVM #BackendDevelopment #JavaInternals #SpringBoot

To view or add a comment, sign in

Explore content categories