java 内存 常量池_jvm字符串常量池在什么内存区域?

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

首先明晰几个概念:

方法区 - 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 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 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.copyOfRange(Arrays.java:2694)

at java.lang.String.(String.java:203)

at java.lang.StringBuilder.toString(StringBuilder.java:405)

at StringOOM.main(StringOOM.java:10)

JDK6-在永久区: OutOfMemoryError: PermGen space

List list = new ArrayList<>(); 无法编译, 必须写完整:List list = new ArrayList();

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 space

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值