A run-time constant pool is a part of a method area that holds information about a class, such as its name, access modifiers, Chang, field descriptions, method descriptions, and so on.
String.intern () is a native method that returns a String object that represents the string in the pool if a string in the constant pool of strings already contains one that is equal to it; Adds the string contained by this string object to the constant pool and returns a reference to this string object. In JDK1.6 and previous versions, because the constant pool is allocated in the permanent generation (i.e., the method area), we can limit the size of the method area by-xx:permsize and-xx:maxpermsize, thereby indirectly restricting the capacity of the constant pool, notice that the JDK1.7 begins to "Go permanent ”。 The code looks like this:
Package Jvm;import java.util.arraylist;import java.util.list;/* * VM Args:-xx:permsize=10m-xx:maxpermsize=10m */ public class Runtimeconstantpooloom {public static void Main (string[] args) { //Use list to keep a constant pool reference to avoid full GC Recycle constant Pool behavior list<string> List = new arraylist<string> (); int i = 0; while (true) { List.add (string.valueof (i++). Intern ())}}}
Note that VM args is configured for the parameters of the configuration VM, as shown in:
Operation Result:
Exception in thread "main" Java.lang.OutOfMemoryError:PermGen space at Java.lang.String.intern (Native Method) At the JVM. Runtimeconstantpooloom.main (RUNTIMECONSTANTPOOLOOM.JAVA:16)
As you can see from the running results, the run-time pool overflow, followed by OutOfMemoryError, is "PermGen space", indicating that the run-time pool is part of the method area (the permanent generation in the Hotspot virtual machine). However, using JDK1.7 to run this program does not result in the same results, but instead, the following message appears because the two parameters are no longer used in JDK1.7.
Java HotSpot (TM) 64-bit Server VM warning:ignoring option permsize=10m; Support is removed in 8.0Java HotSpot (TM) 64-bit Server VM warning:ignoring option maxpermsize=10m; Support is removed in 8.0
If you run the Runtimeconstantpooloom.java program in JDK1.7, the while loop will continue to run, but the while loop does not always run until the heap memory is exhausted in the system, which generally takes a long time to appear, but the author does not test it locally. Because the constant pool stored in JDK1.7 is no longer an object, but an object reference, the real object is stored in the heap. Change the VM parameters of the Runtimeconstantpooloom.java runtime to resemble the following:
-xms20m-xmx20m-xx:+heapdumponoutofmemoryerror
Results after running the program:
Exception message: Java.lang.OutOfMemoryError:GC overhead limit exceeded, there is no hint that the heap or persistent generation problem, the virtual machine just tell you that your program spends too much time on garbage collection, but nothing effective. By default, if you spend 98% of your time on a GC and reclaim less than 2% of the space, the virtual machine throws the exception. This is a good practice for a fast-failing security guarantee. As can be seen from the results of the operation, we limit the size of the heap, the program quickly run the exception, the exception information and the same as previously envisaged, that is, the constant pool storage is no longer an object, but an object reference, the real object is stored in the heap. With regard to the implementation of the JDK1.7 string constant pool, you can also extend a more meaningful effect, as shown in the following code:
Package Jvm;public class Hello {public static void Main (string[] args) { String str1 = new StringBuilder ("Computer"). Ppend ("Software"). ToString (); System.out.println (str1.intern () = = str1); String str2 = new StringBuilder ("Ja"). Append ("va"). toString (); System.out.println (str2.intern () = = str2);} }
This code runs in JDK1.6, gets two false, and runs in JDK1.7, getting a true and a false.
The reasons for this difference are:
In JDK1.6, the Intern () method copies the first encountered string to a permanent generation, and returns a reference to the string in the permanent generation, and the string instance created by StringBuilder is in the Java heap, so it is not necessarily the same reference and will return false.
The Intern () implementation of JDK1.7 (and some other virtual machines, such as JRockit) no longer replicates the instance, but instead records the first occurrence of the instance reference in the constant pool , so intern () The returned reference and the string created by StringBuilder are the same. The str2 comparison returns false because the "Java" string has already appeared before execution of StringBuilder (), has its reference in the string constant pool, does not conform to the "first occurrence" principle, and the "computer Software" string is the first occurrence and therefore returns true.
If the following code is added to the Hello.java, the returned result is also false, proving that the "main" string was also present.
String STR3 = new StringBuilder ("Ma"). Append ("in"). ToString (); System.out.println (str3.intern () = = STR3);
Reference
1, "in-depth understanding of Java Virtual Machine" 2.4.3 chapters
2. String constant pool in Java-Technology little black House
3, where is the permanent Java generation?
4. In-depth understanding of OutOfMemoryError
Http://www.cnblogs.com/luoxn28/p/5425425.html
Analysis of Java method area and run-time pool overflow problem (go)