JDK1.8字符串常量池何去何从

JDK1.8 字符串常量池在内存哪块区域

  • 1、结论
  • 2、验证

我们都知道JDK升级到1.8之后,JVM 的内存结构发生了较大的变动,尤其是元空间 metaspace 取代了永久代,在JDK1.6及其以前,永久代或者说方法区存放了类信息、常量(运行时常量池、字符串常量池)、静态变量以及即时编译后的代码,JDK1.7 将字符串常量池从方法区搬移到堆中,JDK1.8 使用元空间取代了方法区,那么是否JDK1.8只是针对JDK1.7的方法区做了修改,还是说也包含了字符串常量池的修改?这就是我所要验证的;

1、结论

JDK 1.8 是针对 JDK1.7 的方法区做了修改,字符串常量池和JDK1.7一样还是存放在堆中;

2、验证

/**
 * VM Args: -Xms20m -Xmx20m  -XX:+PrintGCDetails -XX:MaxMetaspaceSize=5m -XX:MaxDirectMemorySize=5m -XX:+PrintCommandLineFlags -XX:-UseGCOverheadLimit
 * @author  feiyue
 * @date  2019/9/22
 */
public class RuntimeConstantPoolOOM {
    public static void main(String[] args) {
        List list = new ArrayList<>();
        int i = 0;
        while (true) {
            // 字符串的 intern 方法,字符串常量池会保存新字符串的引用
            list.add(String.valueOf(i++).intern());
            if (i % 1000 == 0) {
            	// 让 minor GC 回收堆内存空间
                list = new ArrayList<>();
            }
            System.out.println(i);
        }
    }
}

如果字符串常量池在元空间中那么上述程序在一定的时间会报java.lang.OutOfMemoryError: Metaspace错,但是上述程序会一直运行下去不会报错,因此验证得以证明;

你可能感兴趣的:(JVM)