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

JVM 垃圾清理 标记-清除算法 常量池移除问题 #747

Closed
ZanderYan-cloud opened this issue Apr 22, 2020 · 17 comments
Closed

JVM 垃圾清理 标记-清除算法 常量池移除问题 #747

ZanderYan-cloud opened this issue Apr 22, 2020 · 17 comments
Labels
bug Content error

Comments

@ZanderYan-cloud
Copy link

该算法分为“标记”和“清除”阶段:首先标记出所有活动的对象,在标记完成后统一回收所有未被标记的对象。
《深入理解jvm》底2版p69的描述“标记-清除算法
该算法分为“标记”和“清除”阶段:首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象。

另外,jdk 7以后只是把字符串常量池从perm区移到了java heap区,不是整个运行时常量池。
[参考博客:
希望楼主参考一下。

@Snailclimb
Copy link
Owner

已经更正!感谢你

@Snailclimb Snailclimb added the bug Content error label Apr 22, 2020
@xionghuyi
Copy link

xionghuyi commented Dec 15, 2021

根据《深入理解Java虚拟机》第三版 P46,JDK7把字符串常量池和静态变量从方法区拿到堆中,而不仅仅是字符串常量池。

@18986293910
Copy link
Contributor

确实不止,原文描述的是把字符串常量池和静态变量等从方法去拿到堆,说明不仅仅是这个两个,还有其他的元素被拿到了堆中

@popsicle256
Copy link

确实不止,原文描述的是把字符串常量池和静态变量等从方法去拿到堆,说明不仅仅是这个两个,还有其他的元素被拿到了堆中

原文讲的是”到了JDK 7的HotSpot,已经把原本放在永久代的字符串常量池、静态变量等移出“,只字未提是移出到堆中

@Snailclimb
Copy link
Owner

确实不止,原文描述的是把字符串常量池和静态变量等从方法去拿到堆,说明不仅仅是这个两个,还有其他的元素被拿到了堆中

原文讲的是”到了JDK 7的HotSpot,已经把原本放在永久代的字符串常量池、静态变量等移出“,只字未提是移出到堆中

image

@popsicle256
Copy link

popsicle256 commented Apr 11, 2022 via email

@Snailclimb
Copy link
Owner

Guide哥你好,没想到能收到你的回复,很高兴,感谢回复。然后你回的这个图中写的是有问题的,《深入理解JVM虚拟机》中原文是我评论引号那段,并没有说明是移到了堆中。然后字符串常量池这块,您在这个里面写的我真的是无力吐槽了,首先声明我是小白哈,我开始是看了您的这个学习的,后面涉及到String s = new String("abc"),这个相关问题的时候我疯狂找资料才发现,您这部分内容实际上错误很多,首先字符串常量池这个概念就不清晰,能找到在JVM规范中相对应的只能是StringTable了,而StringTable根据RednaxelaFX和我所看过的国外某篇介绍字符串字面量的文章中讲到的,它是只存储字符串实例的引用,而不会直接存储实例,而且StringTable的位置一直是在native memory中,变的只是其储存的引用对应的实例存放的位置。而且还一个很关键的是StringTable根本不是运行时常量池的一部分,这是两个不同的东西,没有从属关系,但您这边光从您回复我的这个图中就能看到字符串常量池是“被包含”在运行时常量池的,从《深入理解Java虚拟机》中也找不到字符串常量池是包含在运行时常量池中的。 以上我可能并不是描述的非常清楚,我也只是个刚开始学JVM的小白,而且查了很多资料,关于字符串常量池也还有很多不明白的地方,我想等我把JVM基本流程过完一遍之后,再回来看这个问题应该会更清晰。但虽然我讲的可能不是很清楚,我描述的问题应该您是足够可以明白的吧,如果您有兴趣且有时间,我想您如果能把字符串常量池这部分内容重新编写过,应该会更好。再次感谢您的回复,以及您的guide.cn

---原始邮件--- 发件人: @.> 发送时间: 2022年4月11日(周一) 晚上6:08 收件人: @.>; 抄送: @.@.>; 主题: Re: [Snailclimb/JavaGuide] JVM 垃圾清理 标记-清除算法 常量池移除问题 (#747) 确实不止,原文描述的是把字符串常量池和静态变量等从方法去拿到堆,说明不仅仅是这个两个,还有其他的元素被拿到了堆中 原文讲的是”到了JDK 7的HotSpot,已经把原本放在永久代的字符串常量池、静态变量等移出“,只字未提是移出到堆中 — Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you commented.Message ID: @.***>

感谢指出,我也再找一些资料看看,这部分内容我可能理解的有问题。

@Snailclimb
Copy link
Owner

@popsicle256 字符串常量池我这里理解的就是 StringTable ,我理解错误的点在于认为字符串直接被存在了 StringTable 中,实际并不是,StringTable 存储的仅仅是 String 对象的引用。

@popsicle256
Copy link

@popsicle256 字符串常量池我这里理解的就是 StringTable ,我理解错误的点在于认为字符串直接被存在了 StringTable 中,实际并不是,StringTable 存储的仅仅是 String 对象的引用。

是的,StringTable存储的只是String实例的引用,而StringTable据R大所分析是一直处于native memory中,它和运行时常量池是两个不同的概念,而周志明大佬书中的原话也没有涉及到说字符串常量池是在运行时常量池中的,而这里讲的是从属关系,应该也是不正确的。
image
以下是《深入理解Java虚拟机》第三版原文
image

@Kiwamm
Copy link

Kiwamm commented Apr 27, 2024

根据《深入理解Java虚拟机》第三版 P46,JDK7把字符串常量池和静态变量从方法区拿到堆中,而不仅仅是字符串常量池。

你好,我想问下,在1.8之前,永久代是方法区的实现,也就是说1.8之前,永久代就是方法区。那么永久代不是物理上是在堆内的吗,为啥会有从方法区拿到堆中的说法呢。堆的内存总共可以分为三部分,新生代,老年代以及永久代

@Kiwamm
Copy link

Kiwamm commented Apr 27, 2024

字符
你好,我想问下,在1.8之前,永久代是方法区的实现,也就是说1.8之前,永久代就是方法区。那么永久代不是物理上是在堆内的吗,为啥会有从方法区拿到堆中的说法呢。堆的内存总共可以分为三部分,新生代,老年代以及永久代

@Kiwamm
Copy link

Kiwamm commented Apr 27, 2024

@popsicle256 字符串常量池相关的内容已经完善:https://github.com/Snailclimb/JavaGuide/blob/main/docs/java/jvm/memory-area.mdhttps://github.com/Snailclimb/JavaGuide/blob/main/docs/java/basis/java-basic-questions-02.md

你好,我想问下,在1.8之前,永久代是方法区的实现,也就是说1.8之前,永久代就是方法区。那么永久代不是物理上是在堆内的吗,为啥会有从方法区拿到堆中的说法呢。堆的内存总共可以分为三部分,新生代,老年代以及永久代

@Snailclimb
Copy link
Owner

Snailclimb commented Apr 27, 2024

@popsicle256 字符串常量池相关的内容已经完善:https://github.com/Snailclimb/JavaGuide/blob/main/docs/java/jvm/memory-area.mdhttps://github.com/Snailclimb/JavaGuide/blob/main/docs/java/basis/java-basic-questions-02.md

你好,我想问下,在1.8之前,永久代是方法区的实现,也就是说1.8之前,永久代就是方法区。那么永久代不是物理上是在堆内的吗,为啥会有从方法区拿到堆中的说法呢。堆的内存总共可以分为三部分,新生代,老年代以及永久代

我的理解正确吗:虽然在Java 7及以前的版本中,永久代常被非正式地归类为堆的一部分,但更准确的说法应该是,Java内存被分为两大部分:堆(包括新生代和老年代)和非堆(方法区,其中永久代是方法区在某些JVM实现中的具体表现)。堆这部分用于存储实例对象,非堆用于存放类的元数据信息,包括类的结构、常量池、静态变量等。

@Kiwamm
Copy link

Kiwamm commented Apr 27, 2024

@popsicle256 字符串常量池相关的内容已经完善:https://github.com/Snailclimb/JavaGuide/blob/main/docs/java/jvm/memory-area.mdhttps://github.com/Snailclimb/JavaGuide/blob/main/docs/java/basis/java-basic-questions-02.md

你好,我想问下,在1.8之前,永久代是方法区的实现,也就是说1.8之前,永久代就是方法区。那么永久代不是物理上是在堆内的吗,为啥会有从方法区拿到堆中的说法呢。堆的内存总共可以分为三部分,新生代,老年代以及永久代

虽然永久代物理上是位于 JVM 的堆内存中的,但概念上并不属于堆用于存储实例对象的那部分。这就是为什么有些文献和讨论会讲到“从方法区到堆”的说法。实际上,这种说法可能导致理解上的混淆,因为永久代已经是堆的一部分,只是用途和性质与堆中用于存储实例的部分不同。

哦哦好的,那后面静态变量和字符串常量池移到了堆中,是移到了存储实例对象那部分的内存去了吗

@Snailclimb
Copy link
Owner

在1.8之前,永久代是方法区的实现,也就是说1.8之前,永久代就是方法区。那么永久代不是物理上是在堆内的吗,为啥会有从方法区拿到堆中的说法呢。堆的内存总共可以分为三部分,新生代,老年代以及永久代

@popsicle256 字符串常量池相关的内容已经完善:https://github.com/Snailclimb/JavaGuide/blob/main/docs/java/jvm/memory-area.mdhttps://github.com/Snailclimb/JavaGuide/blob/main/docs/java/basis/java-basic-questions-02.md

你好,我想问下,在1.8之前,永久代是方法区的实现,也就是说1.8之前,永久代就是方法区。那么永久代不是物理上是在堆内的吗,为啥会有从方法区拿到堆中的说法呢。堆的内存总共可以分为三部分,新生代,老年代以及永久代

虽然永久代物理上是位于 JVM 的堆内存中的,但概念上并不属于堆用于存储实例对象的那部分。这就是为什么有些文献和讨论会讲到“从方法区到堆”的说法。实际上,这种说法可能导致理解上的混淆,因为永久代已经是堆的一部分,只是用途和性质与堆中用于存储实例的部分不同。

哦哦好的,那后面静态变量和字符串常量池移到了堆中,是移到了存储实例对象那部分的内存去了吗

可以这么理解。

@Kiwamm
Copy link

Kiwamm commented Apr 28, 2024

在1.8之前,永久代是方法区的实现,也就是说1.8之前,永久代就是方法区。那么永久代不是物理上是在堆内的吗,为啥会有从方法区拿到堆中的说法呢。堆的内存总共可以分为三部分,新生代,老年代以及永久代

@popsicle256 字符串常量池相关的内容已经完善:https://github.com/Snailclimb/JavaGuide/blob/main/docs/java/jvm/memory-area.mdhttps://github.com/Snailclimb/JavaGuide/blob/main/docs/java/basis/java-basic-questions-02.md

你好,我想问下,在1.8之前,永久代是方法区的实现,也就是说1.8之前,永久代就是方法区。那么永久代不是物理上是在堆内的吗,为啥会有从方法区拿到堆中的说法呢。堆的内存总共可以分为三部分,新生代,老年代以及永久代

虽然永久代物理上是位于 JVM 的堆内存中的,但概念上并不属于堆用于存储实例对象的那部分。这就是为什么有些文献和讨论会讲到“从方法区到堆”的说法。实际上,这种说法可能导致理解上的混淆,因为永久代已经是堆的一部分,只是用途和性质与堆中用于存储实例的部分不同。

哦哦好的,那后面静态变量和字符串常量池移到了堆中,是移到了存储实例对象那部分的内存去了吗

可以这么理解。

好的,谢谢了

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Content error
Projects
None yet
Development

No branches or pull requests

6 participants