What Is the Purpose of the Java Constant Pool

What is the purpose of the Java Constant Pool?

I think understanding how the frame is constructed using a diagram would help.

Sample Image

The frame is where the operands (operation instructions) reside and that is where the dynamic linking occurs. It is a shorthand way, so to speak, using the constant pool to keep track of the class and it's members.

Each frame contains a reference to the runtime constant pool. The reference points to the constant pool for the class of the method being executed for that frame. This reference helps to support dynamic linking.

C/C++ code is typically compiled to an object file then multiple object files are linked together to product a usable artifact such as an executable or dll. During the linking phase symbolic references in each object file are replaced with an actual memory address relative to the final executable. In Java this linking phase is done dynamically at runtime.

When a Java file is compiled, all references to variables and methods are stored in the class's constant pool as a symbolic reference. A symbolic reference is a logical reference not a reference that actually points to a physical memory location.

Here is a link to James Blooms JVM Internals for more details.

Why is the constant pool (in Java classfile) indexed from 1 (and not 0)? What is the constant_pool[0] entry reserved for?

They skipped index 0 so that it can be used for cases where you would normally reference a constant pool entry, but instead want to indicate "nothing". It is the constant pool equivalent of a null pointer.

The most notable use for index 0 is for "catch all" exception handlers. An exception handler can either point to the constant pool entry for the class of exceptions it wants to handle, or just use index 0 to catch everything (this is equivalent to catching java/lang/Throwable). In practice, the compiler will generate catch all exception handlers to implement finally, synchronized blocks, and the cleanup portions of try with resources, among other things.

Other uses for index 0 include:

  • The superclass of java/lang/Object
  • The name of a parameter with no name
  • The outer class for classes which are not the member of another class (i.e. top level classes, local classes, and anonymous classes)
  • The inner name of anonymous classes
  • The enclosing method for classes which are not immediately enclosed in a method
  • Version info for a module with no version info
  • Dependencies for a module with no dependency info

Java: Why is constant pool maintained only for String values ?

The purpose of a constant pool is to reduce the memory overhead required by keeping multiple copies of constants. In the case of Strings, the JVM is inherently required to keep some object around for each individually distinguishable constant, and the Java spec basically says that the JVM should deduplicate String objects when class loading. The ability to manually place Strings in the pool via intern is inexpensive and allows programmers to identify particular values (such as properties) that are going to be around for the life of the program and tell the JVM to put them out of the way of normal garbage collection.

Pooling numeric constants, on the other hand, doesn't make a lot of sense, for a few reasons:

  • Most particular numbers aren't ever used in a given program's code.
  • When numbers are used in code, embedding them in the code as immediate opcode values is less expensive in terms of memory than trying to pool them. Note that even the empty String carries around a char[], an int for its length, and another for its hashCode. For a number, by contrast, a maximum of eight immediate bytes is required.
  • As of recent Java versions, Byte, Short, and Integer objects from -128 to 127 (0 to 127 for Character) are precached for performance reasons, not to save memory. This range was presumably chosen because this is the ranged of a signed byte, and it will cover a large number of common uses, while it would be impractical to try to precache a very large number of values.

As a note, keep in mind that the rules about interning were made long before the introduction of autoboxing and generic types in Java 5, which significantly expanded how much the wrapper classes were casually used. This increase in use led Sun to add those common values to a constant pool.

String pool vs Constant pool

My questions are,

  1. Does string pool refers to the pool of constant string object in the constant pool?

No.

"Constant pool" refers to a specially formatted collection of bytes in a class file that has meaning to the Java class loader. The "strings" in it are serialized, they are not Java objects. There are also many kinds of constants, not just strings in it.

See Chapter 4.4 the constant pool table

Java Virtual Machine instructions do not rely on the run-time layout of classes, interfaces, class instances, or arrays. Instead, instructions refer to symbolic information in the constant_pool table.

In contrast, the "String pool" is used at runtime (not just during class loading), contains only strings, and the "strings" in the string pool are java objects.
The "string pool" is a thread-safe weak-map from java.lang.String instances to java.lang.String instances used to intern strings.

Chapter 3.10.5. String Literals says

A string literal is a reference to an instance of class String (§4.3.1, §4.3.3).

Moreover, a string literal always refers to the same instance of class String. This is because string literals - or, more generally, strings that are the values of constant expressions (§15.28) - are "interned" so as to share unique instances, using the method String.intern.

What is Run-Time Constant Pool and Method-Area in java

As per the http://www.artima.com/insidejvm/ed2/jvm2.html

Method area

Some runtime data areas are shared among all of an application's threads and others are unique to individual threads. Each instance of the JVM has one method area and one heap. These areas are shared by all threads running inside the VM. When the VM loads a class file, it parses information about a type from the binary data contained in the class file. It places this type information into the method area.

Runtime Constant Pool

A class file keeps all its symbolic references in one place, the constant pool. Each class file has a constant pool, and each class or interface loaded by the Java virtual machine has an internal version of its constant pool called the runtime constant pool . The runtime constant pool is an implementation-specific data structure that maps to the constant pool in the class file. Thus, after a type is initially loaded, all the symbolic references from the type reside in the type's runtime constant pool.

Need to know about String, String Constant pool and String intern method

I will assume that in each example below you load and execute the code exactly once, in a new JVM each time. (I will also assume that nowhere else in your code do you use the literal "Java" ... since that would complicate things.)


1) Say if there are no strings in the String constant pool, and if i
say,

String s = "Java";

Then how many objects will be created ?

One string is created and added to the pool when method is loaded.


2) Now again nothing in the pool, and i say,

String s = new String("Java");

Now how many objects will be created.

One string is created and added to the pool when method is loaded.

A second string is created by the new when the code is run, and it is NOT added to the pool.


3) Now again nothing in the pool, and i say,

String s = new String("Java");
s.intern();

What will the intern method do ?

One string is created and added to the pool when method is loaded.

A second string is created by the new, and it is NOT added to the pool.

The intern call returns the first string. (You don't keep the reference ...)


4) Now again nothing in the pool, and i say,

String s = new String("Java");
String s1 = s.intern();

What will happen now?

Same as example 3. Thus, s1 will hold a reference to the String object that represents the "Java" string literal.


I read in SCJP5 Kathy Sierra book, that when you create a String with new, then 2 objects are created, one on the heap and one in the pool.

I doubt that the book said that exactly. (You are paraphrasing, and I think you have paraphrased somewhat inaccurately.)

However, your paraphrasing is roughly correct, though (an this is important!) the string object representing the literal is created and added to the pool when the code fragment is loaded1, not when it is executed.


And to address another point of confusion:

"What i actually meant was that from the answer that you gave, it seems that a String will always be added in the String constant pool."

That is incorrect. It is a false generalization.

While it is true for all 4 of the cases above, it will not be true for others. It depends on where the original string came from. In typical applications, most text data is read from a file, socket, or a user interface. When that happens, the strings are created from arrays of characters, either directly or via a library call.

Here is a simple (but unrealistic) example that shows creating a String from its component characters.

String s = new String(new char[]{'J', 'a', 'v', 'a'});

In the snippet above, only one String is created, and it is NOT in the String pool. If you wanted the resulting string to be in the string pool you need to explicitly call intern something like this:

String s = new String(new char[]{'J', 'a', 'v', 'a'});
s = s.intern();

... which will (if necessary) create a second string in the string pool2.


1 - Apparently, in some JVMs creation and interning string literals is done lazily, so it is not possible to say with 100% certainty when it actually happens. However, it will only occur once (per class that references the literal), no matter how many times the code fragment is executed by the JVM.

2 - There is no way to new a string into the string pool. It would actually be a violation of the JLS. The new operation is specified by the JLS as always creating a new object.

Mapping of Constant pool and method Area

Since the literal meaning of “constant pool” is just “pool of constants”, there are different things of the name, which are easy to confuse

  1. Each class file has a constant pool describing all constants used in that class, which includes constant values but also symbolic references needed for linkage. Some entries fulfill both roles, e.g. class entries may serve as owner declaration for a symbolic reference to a member, needed when accessing a field or invoking a method, but may also be used to get a Class instance, e.g. for a class literal appearing in source code. Since it’s part of the class file, its format is specified within The Java® Virtual Machine Specification, §4 The class File Format, in §4.4. The Constant Pool.

    As said by other answers, you can use the command javap -v class.name to inspect the constant pool of a class.

  2. There is a corresponding data structure at runtime, also known as run-time constant pool. Since certain values are represented as runtime objects (e.g. of type String, Class, MethodType, or MethodHandle), and symbolic references must be resolved to the runtime representation of the denoted classes and members, this structure is not the same as the byte sequence found in the class file. But these entries correspond, so that each time, an object is instantiated for a constant or a symbolic reference is resolved, the result can be remembered and reused the next time the same constant entry is accessed.

    This doesn’t imply that an implementation must have a 1:1 representation of each class’ constant pool. It’s possible that a specific implementation maps a class’ pool to a shared pool used for a all classes of the same class loading context, where each symbolic reference resolves to the same target.

  3. There’s also the string pool, which can be seen as part of the runtime constant pool, holding references to all String instances associated with string constants, to allow resolving all identical string constants of all classes to the same String instance.

Is Java String constant pool shared across different JVMs?

A string pool can not be shared between different JVMs. It is implemented as a hash table of references to the actual String objects which live in the particular heap of each JVM. Since references to different heaps are not compatible, as each JVM has its own logical address space, the hash table can’t be shared.

There is a mechanism to share common data between JVMs, Class Data Sharing, which uses a preprocessed form of common libraries, usually of the JRE. Besides the class and member definitions and the byte code, this naturally contains all string constants, but that’s only the data, using the data to create a Java String object with a distinct identity and adding a reference to the pool is still subject to each JVM.

Understanding javap's output for the Constant Pool

All your class, interface, field names and string constants go into the java constant pool.

As per VM Spec ( http://java.sun.com/docs/books/jvms/second_edition/html/ClassFile.doc.html ):

The constant_pool is a table of
structures (§4.4) representing various
string constants, class and interface
names, field names, and other
constants that are referred to within
the ClassFile structure and its
substructures. The format of each
constant_pool table entry is indicated
by its first "tag" byte. The
constant_pool table is indexed from 1
to constant_pool_count-1.

So in terms of constant pool something like below can be viewed as:

const #22 = String      #23;    //  hello world
const #23 = Asciz hello world;

The value at #22 (index 22) is of type String and its value is null terminated c string (Asciz) hello world is at index 23.



Related Topics



Leave a reply



Submit