jvm字符串常量池在什麼內存區域?

問題:字符串常量池分配在什麼內存區域? 方法區?永久區? 堆內存?java


首先明晰幾個概念:app

  • 方法區 - java虛擬機規範運行時數據區

方法區 概念屬於 java虛擬機規範運行時數據區的一部分. 運行時數據區包括: 程序計數器java虛擬機棧本地方法棧java堆方法區. 其中, 方法區java堆 都是全部線程共享的數據區, 用於存放已被jvm加載的class信息、常量、static變量、JIT即時編譯後的代碼等這些數據.jvm

  • 永久區 - jvm實現

永久區又叫PermGen, 是jvm實現, 且只存在於jdk7和以前的版本;jdk8中已完全移除PermGen,jdk8引入了一個新的內存區域:metaspace;ui

而後再看下面程序的輸出, 可肯定java的版本 jdk6/7/8中的字符串分配的內存區域. 運行時指定 VM Options參數 java -Xms20m -Xmx20m StringOOM 令程序內存過限:spa

import java.util.ArrayList;
import java.util.List;

public class StringOOM {
    static String base = "somethings";

    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        for (int i = 0; i < Integer.MAX_VALUE; i++) {
            String str = base + base;
            base = str; // 只是用來增加
            /** intern 會把字符串發佈到 字符串常量池中去 */
            list.add(str.intern());
        }
    }
}

JDK8-在堆內存: OutOfMemoryError: Java heap space線程

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Arrays.java:3332)
at java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:124)
at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:448)
at java.lang.StringBuilder.append(StringBuilder.java:136)
at com.niewj.demo.lang.StringOOM.main(StringOOM.java:12)
Java HotSpot(TM) 64-Bit Server VM warning: ignoring option PermSize=8m; support was removed in 8.0
Java HotSpot(TM) 64-Bit Server VM warning: ignoring option MaxPermSize=8m; support was removed in 8.0

JDK7-在堆內存: OutOfMemoryError: Java heap spacecode

PS C:\devs\java\jdk7\bin> .\java.exe -Xms20m -Xmx20m -XX:PermSize=8m -XX:MaxPermSize=8 StringOOM
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOfRange(Arrays.java:2694)
at java.lang.String.<init>(String.java:203)
at java.lang.StringBuilder.toString(StringBuilder.java:405)
at StringOOM.main(StringOOM.java:10)

JDK6-在永久區: OutOfMemoryError: PermGen space內存

List<String> list = new ArrayList<>(); 沒法編譯, 必須寫完整:List<String> list = new ArrayList<String>();
PS C:\devs\java\jdk6> .\bin\java.exe StringOOM
Exception in thread "main" java.lang.OutOfMemoryError: PermGen space
at java.lang.String.intern(Native Method)
at StringOOM.main(StringOOM.java:12)

結論:
JDK6-在永久區: OutOfMemoryError: PermGen space
JDK7-在堆內存: OutOfMemoryError: Java heap space
JDK8-在堆內存: OutOfMemoryError: Java heap spaceci

可見, JDK6的jvm 對字符串常量池的內存區域的實現, 還在永久區(PermGen); 而JDK7/JDK8就都是在堆內存中劃分的內存了;rem

相關文章
相關標籤/搜索