都知道jdk8去除了永久代,用元空间去实现方法区,以前认为方法区是包含运行时常量池和class类型数据,后来看文章说是jdk7把运行时常量池从永久代移到堆中,那么jdk8里运行时常量池是在堆中还是元空间里呢?
先说结论:在堆中。
写个例子:
/**
* -Xms2m
* -Xmx2m
* 验证运行时常量池在堆还是直接内存
*/
private static void functionOut() {
int i = 0;
while (true) {
("hello" + i++).intern(); //intern方法会把第一次遇见的字符串存到运行时常量区里
}
}
直接在main方法执行后:
java.lang.OutOfMemoryError: Java heap space
内存溢出了,看来常量池是在堆中了。
在写个对照的例子,只是修改了jvm参数,限制元空间大小为10m:
/**
* -XX:MaxMetaspaceSize=10m
* 验证运行时常量池在堆还是直接内存
*/
private static void functionOut2() {
int i = 0;
while (true) {
("hello" + i++).intern();
}
}
运行了几分钟没报错。