JVM.ConstantPool.How are constant pool entries stored and accessed by the JVM?

💾 What is the Constant Pool?

The constant pool is a table stored inside every .class file. It contains a list of symbolic references used by the class — essentially, all the constants and symbolic metadata the class needs.


📜 What Kind of Entries are Stored?

Here’s what you’ll find in a constant pool:

Type of EntryExamples
LiteralsString literals like "Hello World", numbers like 123, 3.14, etc.
Class ReferencesReferences to other class names like java/lang/String
Method ReferencesReferences to method signatures like println(Ljava/lang/String;)V
Field ReferencesReferences to fields like System.out
Type InformationTypes used in methods or fields (I, Ljava/lang/String;, etc.)
InvokeDynamic InfoFor lambdas and dynamic method handles (since Java 7/8)

📦 Where is the Constant Pool Stored?

1️⃣ In the .class File

  • When you compile your code, javac generates a .class file.
  • Inside that file, there’s a constant pool table at the very top.
  • You can see it using:




javap -verbose MyClass

It looks something like this:

Constant pool:
   #1 = Methodref          #6.#23       // java/lang/Object."<init>":()V
   #2 = Fieldref            #24.#25      // java/lang/System.out:Ljava/io/PrintStream;
   #3 = String              #26          // Hello World
   #4 = Methodref           #27.#28      // java/io/PrintStream.println:(Ljava/lang/String;)V

2️⃣ In JVM Memory (Method Area)

  • When the class is loaded, this constant pool is copied into the JVM’s Method Area.
  • Inside the Method Area, each loaded class has its own runtime constant pool.

🏃‍♂️ How Does the JVM Access Constant Pool Entries?

This is where the bytecode instructions come in. Most bytecode instructions don’t store hard-coded values — instead, they store an index into the constant pool.

For example, if the bytecode wants to print a string like "Hello World", it might look like this:

ldc #3  // load constant #3 from the constant pool (which is "Hello World")
invokevirtual #4 // call println(String), found at entry #4

⚙️ Runtime Process

Here’s how it works step-by-step:

  1. Bytecode instruction says: ldc #3.
  2. The JVM:
    • Looks at the constant pool entry #3.
    • Sees that entry #3 is a String constant: "Hello World".
    • Loads "Hello World" into the operand stack.
  3. The next instruction says: invokevirtual #4.
  4. The JVM:
    • Looks at the constant pool entry #4.
    • Sees it’s a method reference to PrintStream.println(String).
    • Resolves the actual method pointer.
    • Invokes the method.

📊 Constant Pool Example in Action

For this code:

System.out.println("Hello World");

The constant pool might contain:

IndexTypeValue
1Classjava/lang/System
2FieldrefSystem.out
3String“Hello World”
4MethodrefPrintStream.println(String)

The bytecode would look something like:

getstatic #2    // Load System.out
ldc #3          // Load constant "Hello World"
invokevirtual #4 // Call println(String)

🚀 Why Use a Constant Pool?

  • Compact bytecode: Bytecode only needs small indexes instead of large names.
  • Flexibility: Constant pool allows symbolic resolution — actual addresses are resolved at runtime.
  • Portability: Symbolic resolution makes it easier to link classes dynamically across different JVM versions.

🔥 Special Case: String Pool

  • String literals in the constant pool can also be interned, meaning they are placed into the String Pool (part of the Heap, outside the Method Area).
  • This is why "Hello".intern() can return the same object across different classes.

✅ Quick Summary

StepWhat Happens
CompileConstant pool is written into .class file
Class LoadConstant pool is copied into Method Area
Bytecode ExecutionBytecode instructions access constants via index into constant pool
LinkingConstant pool entries are resolved to actual classes, methods, and fields when first used

💡 In Short

✔️ Constant pool is like the symbol table for a class.
✔️ It supports literals, symbolic references, and method/field signatures.
✔️ JVM bytecode accesses data indirectly through the pool, keeping bytecode small and flexible.
✔️ The constant pool is essential for dynamic linking and reflection.

This entry was posted in Без рубрики. Bookmark the permalink.