Java程序的内存区域是什么?

3
我一直在应用程序层面工作,因此还没有深入研究Java程序运行时内存的处理方式。最近我遇到了一个问题,需要了解这些知识以解决应用性能问题。
我知道Java中有“栈”和“堆”的内存区域模型,但事实证明情况远不止如此。
例如,我发现了一些术语,如Eden、s0、s1、Old memory等,之前我从未听说过这些术语。
随着Java的更新,这些术语可能已经失去了相关性,也可能仍然存在于Java 8中。
请问有人可以指导我在何处获取这些信息,以及在何种情况下需要了解它们?它们是否是主内存(即RAM)的一部分?

2
请注意,原始标签中提到的Java内存模型实际上并不关心这些术语,而是描述了Java多处理器环境中内存访问的工作方式(关键字:读/写屏障,先行发生关系等)。 - Joachim Sauer
@JoachimSauer:非常感谢您的信息。所以JMM标记是关于“读/写”,而不是Java程序看到的内存模型? - CuriousMind
1
嗯,它确实是关于Java在内存中看到的模型(因此得名),但它不是一个“这就是Java知道的关于内存的一切”的模型,并且不关心堆栈或其他你提到的区别。 - Joachim Sauer
2个回答

4
Eden、s0、s1、老年代和其他内存区域仅存在于特定垃圾收集器实现的上下文中,例如类似G1的分代收集器将堆划分为所述区域,但非分代收集器如ZGC则不会。
首先,请查看JVM中的主要垃圾收集器: - ParNew - CMS - G1 - ZGC / Shenandoah / Azul C4
然后尝试理解相关概念: - 线程本地分配缓冲区(TLAB) - 逃逸分析 - 字符串常量池、字符串interning、字符串去重 - 永久代与元空间 - 对象布局,例如为什么 boolean 不占用1个位(字撕裂) - 本机内存,例如JNI或非堆内存访问
我不相信有一个单一的网站可以解释完整的JVM内存管理方法。

非常感谢Karol的回复和分享知识。 - CuriousMind

3
Java,由Java 语言规范和 Java 虚拟机规范定义,讨论了堆栈(以及方法区)。
这些是用于概念上描述 Java 虚拟机的必要内容。
如果您想要实现 JVM,您需要以某种方式实现它们。它们在 Java 13 中与 Java 1 时一样有效。关于它们的工作原理没有根本性的改变。
您提到的其他术语(以及“old gen”,“new gen”等)是实现Oracle JDK / OpenJDK中特定垃圾回收机制使用的内存区域。
所有这些区域基本上都是堆的特定部分。堆如何分成这些区域的确切方式取决于垃圾收集器的决定,除非您想要调整垃圾收集器,否则不需要了解它们。

由于垃圾收集器在发布之间会发生变化,并且新的垃圾收集器方法经常被实施(因为这是加速JVM的主要方式之一),因此这里使用的具体术语将随着时间的推移而改变。


感谢Joachim Sauer的回答。所以,如果我暂时不考虑垃圾收集器,那么内存只是“RAM”,并且被分为“堆栈”和“堆”? - CuriousMind
1
是的,基本上这是一个“你想挖得有多深”的问题。从高层次的角度来看,Java程序的内存被分为“堆栈”和“堆”。如果你深入挖掘并查看特定实现,你可能会发现堆实际上被分成了所有那些对垃圾回收器非常重要的其他部分。 - Joachim Sauer
感谢Joachim Sauer的回复。如果我想要理解它,您能告诉我从哪里开始吗?当然,互联网上有很多信息,但其中可能有太多细节是正确或不正确的。而我只是刚刚开始涉足这个领域。感谢您的时间和分享深度知识。 - CuriousMind
1
@CuriousMind:Karol发布了一个有关相关主题的好列表,值得研究。我只能告诉你“去了解这些东西”。据我所知,没有一个单一的来源可以教你所有这些。 - Joachim Sauer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接