The Wayback Machine - https://web.archive.org/web/20201013054134/https://github.com/Snailclimb/JavaGuide/issues/613
Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

不同常量池在 JDK6~8 中存放的位置 #613

Open
jiabinl opened this issue Jan 5, 2020 · 2 comments
Open

不同常量池在 JDK6~8 中存放的位置 #613

jiabinl opened this issue Jan 5, 2020 · 2 comments

Comments

@jiabinl
Copy link
Contributor

@jiabinl jiabinl commented Jan 5, 2020

根据 https://www.javatt.com/p/47643

JVM 中有三类常量池

  1. 静态常量池(class 文件中的常量池)
  2. 运行时常量池
  3. 字符串常量池

他们再 JDK6~8 中分别位于不同的地方

在JDK6及之前的版本:
静态常量池在Class文件中。
运行时常量池在Perm Gen区(也就是方法区)中。(所谓的方法区是在Java堆的一个逻辑部分,为了与Java堆区别开来,也称其为非堆(Non-Heap),那么Perm Gen(永久代)区也被视为方法区的一种实现。)
字符串常量池在运行时常量池中。

在JDK7版本:
静态常量池在Class文件中。
运行时常量池依然在Perm Gen区(也就是方法区)中。在JDK7版本中,永久代的转移工作就已经开始了,将譬如符号引用(Symbols)转移到了native heap;字面量(interned strings)转移到了java heap;类的静态变量(class statics)转移到了java heap。但是运行时常量池依然还存在,只是很多内容被转移,其只存着这些被转移的引用。网上流传的一些测试运行时常量池转移的方式或者代码,其实是对字符串常量池转移的测试。

在JDK8版本:
静态常量池在Class文件中。
JVM已经将运行时常量池从方法区中移了出来,在Java 堆(Heap)中开辟了一块区域存放运行时常量池。同时永久代被移除,以元空间代替。元空间并不在虚拟机中,而是使用本地内存。因此,默认情况下,元空间的大小仅受本地内存限制。其主要用于存放一些元数据。
字符串常量池存在于Java堆中。

请问这三类常量池在 JDK6~8 中分别如何对应到 JVM 的内存模型中?

@jiabinl
Copy link
Contributor Author

@jiabinl jiabinl commented Jan 5, 2020

有的文章把 class 常量池归入 运行时常量池,如 https://segmentfault.com/q/1010000018015110

  • 运行时常量池是全局共享的,class常量池是class文件编译时确定的;
  • 虚拟机加载Class之后会把class常量池中的数据放入到运行时常量池。
  • String常量池位置:
    • jdk1.6: 永久代(方法区)
    • jdk1.7: 堆内存
    • jdk1.8: 元空间

有些文章并没有区分不同类型的常量池,笼统地得出结论,如 https://blog.csdn.net/qq_42629806/article/details/99842776

  • Jdk1.6及之前:有永久代,常量池1.6在方法区
  • Jdk1.7:有永久代,但已经逐步“去永久代”,常量池1.7在堆
  • Jdk1.8及之后:无永久代,常量池1.8在元空间
@Snailclimb
Copy link
Owner

@Snailclimb Snailclimb commented Jan 13, 2020

赞!老哥。加深了我对常量池的理解。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
2 participants
You can’t perform that action at this time.