ChatGPT解决这个技术问题 Extra ChatGPT

Java 堆术语:年轻代、年老代和永久代?

我试图理解 Java 堆术语中年轻代、老代和永久代的概念,更具体地说是三代之间的交互。

我的问题是:

什么是年轻一代?

什么是老一代?

什么是永久世代?

三代人如何相互作用/相互关联?

假设您谈论的是 Sun JDK/OpenJDK,请参阅 Storage Management 上 OpenJDK 网站上的页面。底部有几个链接指向更多信息。
也与“tenured generation”这个问题有关

H
Hearen

这似乎是一个普遍的误解。在 Oracle 的 JVM 中,永久代不是堆的一部分。它是类定义和相关数据的单独空间。在 Java 6 及更早版本中,实习字符串也存储在永久代中。在 Java 7 中,interned 字符串存储在主对象堆中。

这是 permanent generation 上的一篇好帖子。

我喜欢 Oracle 的 guide on JConsole 中对每个空格的描述:

对于 HotSpot Java VM,串行垃圾回收的内存池如下。 Eden Space(堆):最初为大多数对象分配内存的池。幸存者空间(堆):包含在伊甸空间的垃圾收集中幸存下来的对象的池。 Tenured Generation (heap):包含在幸存者空间中存在一段时间的对象的池。永久代(非堆):包含虚拟机本身的所有反射数据的池,例如类和方法对象。对于使用类数据共享的 Java VM,这一代分为只读区和读写区。代码缓存(非堆):HotSpot Java VM 还包括一个代码缓存,其中包含用于编译和存储本机代码的内存。

Java 使用分代垃圾收集。这意味着如果你有一个对象 foo(它是某个类的实例),它存活的垃圾收集事件越多(如果仍然有对它的引用),它被提升得越远。它从年轻一代开始(它本身被划分为多个空间 - 伊甸园和幸存者),如果它存活足够长的时间,最终将在终身一代结束。


我相信从 Java 7 开始,字符串不再被保留在永久代中。
你是对的,我很惊讶它在被提及之前存活了这么久。然后在 Java 8 中,永久代将被元空间取代(尽管我不确定这将有多大不同,除了默认情况下是无界的)
约书亚——“老”是“终身”的同义词,“新”是“幸存者”的同义词?
perm gen 仅适用于 Java 8 之前的版本。
如果您仍在等待答案,是的,您是对的@joadha。查看此链接:codeahoy.com/2017/08/06/basics-of-java-garbage-collection
P
Premraj

堆分为年轻代和年老代,如下所示:

年轻一代:是短期居住的地方,分为两个空间:

伊甸园(亚当和夏娃第一次生活)空间:当使用在该空间上分配的新关键字内存创建对象时。

幸存者空间:这是一个池,其中包含在从 Eden 空间进行 Java 垃圾收集后幸存的对象。

老年代:这个池基本上包含永久和虚拟(保留)空间,并将保存那些在年轻代垃圾收集后幸存下来的对象。

Tenured Space:这个内存池包含多次垃圾回收后存活的对象,意思是从 Survivor 空间进行垃圾回收后存活的对象。

永久代:这个内存池,顾名思义,包含永久类元数据和描述符信息,因此永久代空间始终保留给类和与类相关的那些,例如静态成员。

Java8 更新:PermGen 被替换为非常相似的 Metaspace。主要区别在于元空间动态调整大小,即它可以在运行时扩展。 Java 元空间空间:无界(默认)

代码缓存(虚拟或保留):如果您使用的是 HotSpot Java VM,这包括代码缓存区域,其中包含将用于编译和存储本机代码的内存。

https://i.stack.imgur.com/eP0SJ.png

Courtesy


@Premraj Metaspace 动态调整大小是什么意思,即它可以在运行时扩展。 ?唯一的区别是默认情况下它没有上边框?
太好了..我可以知道这张图片中的方法区、nativestack 和运行时常量池在哪里吗?他们持有什么?
如果代码缓存用于本机方法代码,本机方法堆栈(每个线程都有一个)会有什么?
H
Hearen

什么是年轻一代?

年轻代是所有新对象被分配和老化的地方。当年轻代填满时,这会导致次要垃圾收集。一个充满死亡对象的年轻代很快就会被收集起来。一些幸存的对象被老化并最终移动到老年代。

什么是老一代?

老一代用于存储长期存活的对象。通常,为年轻代对象设置一个阈值,当满足该年龄时,该对象将移动到老年代。最终需要收集老年代。此事件称为重大垃圾回收

什么是永久世代?

永久代包含 JVM 所需的元数据,用于描述应用程序中使用的类和方法。 JVM 在运行时根据应用程序使用的类填充永久代。

自 Java 8 发布以来,PermGen 已被 Metaspace 取代。

PermSize & MaxPermSize 参数现在将被忽略

三代人如何相互作用/相互关联?

https://i.stack.imgur.com/ldFRR.png

图片来源oracle technetwork 教程文章:http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html

上面文章中的“一般垃圾收集过程”用许多图表解释了它们之间的交互。

看一下总结图:

https://i.stack.imgur.com/bN2Tu.png


太好了..我可以知道这张图片中的方法区、nativestack 和运行时常量池在哪里吗?他们持有什么?
有关详细信息,请参阅 docs.oracle.com/javase/specs/jvms/se7/html/jvms-2.html。方法区是在虚拟机启动时创建的。尽管方法区在逻辑上是堆的一部分,但简单的实现可能会选择不进行垃圾收集或压缩它。每个运行时常量池都是从 Java 虚拟机的方法区分配的
你确定......我一直在阅读它的永久空间(不是堆)的一部分吗? journaldev.com/2856/…
Oracle 文档更真实
是否以时间单位(例如 ms)为年轻代对象设置阈值?还是 GC 轮次?
M
Mark R

Java 虚拟机分为三代:年轻代、老一代和永久代。大多数对象最初是在年轻代中分配的。老年代包含在一定数量的年轻代集合中幸存下来的对象,以及一些可能直接在老年代中分配的大对象。永久代保存 JVM 认为便于垃圾收集器管理的对象,例如描述类和方法的对象,以及类和方法本身。


K
KrityAg

SunHotSpot JVM 中的内存分为三代:年轻代、老一代和永久代。

Young Generation:新创建的对象分配给young gen。

老一代:如果新对象请求更大的堆空间,它会直接分配到老一代。在几个 GC 周期中幸存下来的对象也会被提升到老一代,即老一代中的长寿命对象。

永久代:永久代保存 JVM 认为便于垃圾收集器管理的对象,例如描述类和方法的对象,以及类和方法本身。

仅供参考:永久生成不被视为 Java 堆的一部分。

三代人如何相互作用/相互关联?对象(大对象除外)首先分配给年轻代。如果一个对象在 x 之后仍然活着。垃圾收集周期它被提升到老/老一代。因此,我们可以说年轻代包含寿命短的对象,而老代包含寿命长的对象。永久代不与其他两代互动。