开发者

jvm字符串常量池在什么内存区域问题解析

开发者 https://www.devze.com 2023-11-20 11:05 出处:网络 作者: 丰木
目录问题 字符串常量池分配在什么内存区域? 方法区?永久区? 堆内存?永久区 - jvm实现JDK8-在堆内存: OutOfMemoryError: Java heap spaceJDK7-在堆内存: OutOfMemoryError: Java heap spaceJDK6-在永久区:
目录
  • 问题 字符串常量池分配在什么内存区域? 方法区?永久区? 堆内存?
    • 永久区 - jvm实现
    • JDK8-在堆内存: OutOfMemoryError: Java heap space
    • JDK7-在堆内存: OutOfMemoryError: Java heap space
    • JDK6-在永久区: OutOfMemoryError: PermGen space
  • 结论

    问题 字符串常量池分配在什么内存区域? 方法区?永久区? 堆内存?

    首先明晰几个概念:

    • 方法区 - java虚拟机规范运行时数据区

    方法区 概念属于 java虚拟机规范运行时数据区的一部分. 运行时数据区包括: 程序计数器java虚拟机栈本地方法栈java堆方法区. 其中, 方法区 跟 java堆 都是所有线程共享的数据区, 用于存放已被jvm加载的class信息、常量、static变量、JIT即时编译后的代码等这些数据.

    永久区 - jvm实现

    永久区又叫PermGen, 是jvm实现, 且只存在于jdk7和之前的版本;jdk8中已彻底移除PermGen,jdk8引入了一个新的内存区域:metASPace;

    然后再看下面程序的输出, 可确定java的版本 jdk6/7/8中的字符串分配的内存区域.

    运行时指定 VM Options参数 java -Xms20m -Xmx20m StringOOM 令程序内存过限:

    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.OutOfEIVXXNMemoryError: Java heap space
    at java.util.Arrays.copyOf(Arrays.java:3332)
    at java.lang.AbstractStringjavascriptBuilder.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 space

    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.candroidopyOfRange(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\pythonjava\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 space

    可见, JDK6的jvm 对字符串常量池的内存区域的实现, 还在永久区(PermGen); 而JDK7/JDK8就都是在堆内存中划分的内存了;

    以上就是jvm字符串常量池在什么内存区域问题解析的详细内容,更多关于jvm字符串常量池内存区域的资料请关注编程客栈(www.devze.com)其它相关文章!

    0

    精彩评论

    暂无评论...
    验证码 换一张
    取 消

    关注公众号