作者回复: 对的
作者回复: 感谢Xiao同学的提醒。
我想你说的内存模型应该是指Java内存模型(JMM)吧。这里的JVM内存模型跟Java内存模型是不一样的,这里的JVM内存模型和和内存结构是一个意思。
元空间是分配的本地内存,文中开始描述不清楚(已纠正),但后面有明确说明。
作者回复: 方法区不是堆的一部分,方法区和堆存在交集。方法区的静态变量和运行时常量池存放在堆中,但类的元信息等还是存放在了本地内存中。
作者回复: 正确
作者回复: 严格来说,是静态常量池和运行时常量池,静态常量池是存放字符串字面量、符号引用以及类和方法的信息,而运行时常量池存放的是运行时一些直接引用。
运行时常量池是在类加载完成之后,将静态常量池中的符号引用值转存到运行时常量池中,类在解析之后,将符号引用替换成直接引用。
这两个常量池在JDK1.7版本之后,就移到堆内存中了,这里指的是物理空间,而逻辑上还是属于方法区(方法区是逻辑分区)。
作者回复: 元空间主要存储类的一些信息,包括方法、字段、类等描述类信息。
作者回复: 本地内存是一种非JVM堆内存
作者回复: 是的,没有变化。
作者回复: 对的,这里是申请一个线程栈。
作者回复: 在逻辑空间是属于方法区。堆、栈、方法区等,这些是一种规范,是逻辑上的分区。
在物理空间中,常量池是存储在堆内存空间的。
作者回复: 方法区是一个规范,并不是一个物理空间,我们这里说的字符串常量放在堆内存空间中,是指实际的物理空间。
作者回复: 而到了 Java8,永久代被元空间取代了,元空间存储静态变量...
以上这句话描述不准确。将元空间去掉。元空间是使用的本地内存,在后面讲述到了:“并且元空间的存储位置是本地内存”
作者回复: 字符串常量存储在了常量池,引用在运行时存放在了栈中。new String("")是会创建一个新对象的,可以查看一下构造函数:
public String(String original) {
this.value = original.value;
this.hash = original.hash;
}
作者回复: 是的,调换下位置方便更好理解JIT,因为JIT用到了JVM内存的知识点。声明下,这里不是JMM,JMM是Java Memory Model,而我们这节讲的是JVM的内存模型(Java Virtual Machine Structure)。
作者回复: 我们说的是JVM的内存模型(Java Virtual Machine Structure),不是JMM(Java Memory Model)。
作者回复: 两者有区别,通常方法区中有静态常量池和运行时常量池,静态常量池主要存储的是字面量以及符号引用等信息,而运行时常量池存储的是类运行加载时生成的直接引用等信息。静态常量池也包括了我们说的字符串常量池。
作者回复: 对的,此处的数量是指CPU核数
作者回复: 从官方文档解释,class metadata is stored in a new space called Metaspace,所以并没有指出有其他内容存放在元空间。具体的可以参考以下链接:
https://www.oracle.com/webfolder/technetwork/tutorials/mooc/JVM_Troubleshooting/week1/lesson1.pdf