Interned Strings Stored in Heap

This section provides a tutorial example that shows interned String objects are stored in the Heap data area in HotSpot 1.8 and in Runtime Constant Pool in HotSpot 1.6.

Another possible reason for running out of memory on the Method Area is not enough space in the Runtime Constant Pool, which is part of the Method Area.

It's not so easy to create a Java class with a large amount of contents to fill the Runtime Constant Pool. But based a blog by "chaofanwei" at http://blog.csdn.net/chaofanwei/article/details/19483101, we can use the intern() method to put any dynamically generated string into the Runtime Constant Pool. So here is my sample program, MethodAreaStringIntern.java, trying to force an OutOfMemoryError on the Runtime Constant Pool.

/* MethodAreaStringIntern.java
 * Copyright (c) 2014, HerongYang.com, All Rights Reserved.
 */
import java.util.*;  
public class MethodAreaStringIntern {  
   public static void main(String[] args) {  
      List<String> buffer = new ArrayList<String>();
      long base = 1000000000;
      heapCheck();
      for (int n=0; n<1000; n++) {
         for (int i=0; i<10*1024; i++) {
            StringBuffer tmp = new StringBuffer();
            for (int k=0; k<16; k++) 
               tmp.append("String"+(base+n)+"String"+(base+i));
            buffer.add((tmp.toString()).intern());
         }
         System.out.println((n+1)+": "
            +(n+1)*10+" MB of strings created.");
         heapCheck();
      }
   }
   public static void heapCheck() {
      Runtime rt = Runtime.getRuntime();
      rt.gc();
      long total = rt.totalMemory();
      long free = rt.freeMemory();
      long used = total - free;
      java.io.Console con = System.console();
      con.format("Total memory: %s%n",total);
      con.format(" Free memory: %s%n",free);
      con.format(" Used memory: %s%n",used);
      String str = con.readLine("Press ENTER key to continue: ");
   }
}

This program is designed to:

Compile and run with HotSpot JVM 1.8:

C:\>\progra~1\java\jdk1.8.0\bin\javac MethodAreaStringIntern.java

C:\>\progra~1\java\jdk1.8.0\bin\java MethodAreaStringIntern
Total memory: 16318464
 Free memory: 16063672
 Used memory: 254792
Press ENTER key to continue:
1: 10 MB of strings created.
Total memory: 27131904
 Free memory: 15885256
 Used memory: 11246648
Press ENTER key to continue:
2: 20 MB of strings created.
Total memory: 53178368
 Free memory: 31180880
 Used memory: 21997488
Press ENTER key to continue:
...
23: 230 MB of strings created.
Total memory: 259522560
 Free memory: 9586384
 Used memory: 249936176
Press ENTER key to continue:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
   at java.util.Arrays.copyOfRange(Arrays.java:3658)
   at java.lang.StringBuffer.toString(StringBuffer.java:671)
   at MethodAreaStringIntern.main(MethodAreaStringIntern.java:15)

Surprisingly, the output shows that: Interned string objects are stored in the Heap data area, not in the Runtime Constant Pool. Searching the Internet again, I found that interned strings are stored in Runtime Constant Pool in HotSpot 1.6 and earlier. But since HotSpot 1.7, they are stored in the Heap now.

Compile and run with HotSpot JVM 1.6:

C:\>\progra~1\java\jdk1.6.0_45\bin\javac MethodAreaStringIntern.java

C:\>\progra~1\java\jdk1.6.0_45\bin\java MethodAreaStringIntern
Total memory: 16318464
 Free memory: 16194024
 Used memory: 124440
Press ENTER key to continue:
1: 10 MB of strings created.
Total memory: 16318464
 Free memory: 16122144
 Used memory: 196320
Press ENTER key to continue:
2: 20 MB of strings created.
Total memory: 16318464
 Free memory: 16063256
 Used memory: 255208
Press ENTER key to continue:
...
6: 60 MB of strings created.
Total memory: 16318464
 Free memory: 15828864
 Used memory: 489600
Press ENTER key to continue:
Exception in thread "main" java.lang.OutOfMemoryError: PermGen space
        at java.lang.String.intern(Native Method)
        at MethodAreaStringIntern.main(MethodAreaStringIntern.java:15)

Ok. The output confirmed that HotSpot 1.6 stores interned strings in the Runtime Constant Pool, which is called "PermGen space".

Last update: 2014.

Table of Contents

 About This Book

 Downloading and Installing JDK 1.8.0 on Windows

 Downloading and Installing JDK 1.7.0 on Windows

 java.lang.Runtime Class - The JVM Instance

 java.lang.System Class - The Operating System

 ClassLoader Class - Class Loaders

 Class Class - Class Reflections

 Sun's JVM - Java HotSpot VM

 JRockit JVM 28.2.7 by Oracle Corporation

JVM Runtime Data Areas

 What Are Runtime Data Areas?

 Method Area Expansion Demonstration

 OutOfMemoryError on the Method Area

 Method Area Growth with Dynamically Generated Classes

 Garbage Collection Issue with Dynamically Generated Classes

Interned Strings Stored in Heap

 Heap Expansion Demonstration

 Direct Memory Expansion Demonstration

 allocateMemory() Method on Direct Memory

 JVM Stack Expansion Demonstration

 PC Register and Native Method Stack

 Memory Management and Garbage Collectors

 Garbage Collection Tests

 JVM Stack, Frame and Stack Overflow

 Thread Testing Program and Result

 CPU Impact of Multi-Thread Applications

 I/O Impact of Multi-Thread Applications

 CDS (Class Data Sharing)

 Micro Benchmark Runner and JVM Options

 Micro Benchmark Tests on "int" Operations

 Micro Benchmark Tests on "long" Operations

 Micro Benchmark Tests in JIT Compilation Mode

 Micro Benchmark Tests on "float" and "double" Operations

 Outdated Tutorials

 References

 PDF Printing Version