我试图理解年轻,旧和永久世代的概念在Java堆术语中是什么,更具体地说三代人之间的相互作用。
我的问题是:
答案 0 :(得分:277)
这似乎是一种常见的误解。在Oracle的JVM中,永久代不是堆的一部分。它是类定义和相关数据的独立空间。在Java 6及更早版本中,实习字符串也存储在永久代中。在Java 7中,实习字符串存储在主对象堆中。
这是permanent generation上的一篇好文章。
我喜欢Oracle guide on JConsole中每个空格的描述:
对于HotSpot Java VM,内存 用于串行垃圾收集的池 如下。
- Eden Space(堆):最初分配内存的池 对于大多数物体。
- 幸存者空间(堆):包含幸存对象的池 伊甸园的垃圾收集 空间。
- Tenured Generation(堆):包含已存在的对象的池 在幸存者的一段时间里。
- 永久生成(非堆):包含所有反射的池 虚拟机本身的数据, 例如类和方法对象。同 使用类数据共享的Java VM, 这一代分为 只读和读写区域。
- 代码缓存(非堆):HotSpot Java VM还包括代码缓存, 包含用于的内存 本地的编译和存储 代码。
Java使用分代垃圾收集。这意味着如果你有一个对象foo(它是某个类的一个实例),它存活的垃圾收集事件就越多(如果仍有对它的引用),它就会被进一步提升。它始于年轻一代(它本身被分为多个空间 - 伊甸园和幸存者),如果它存活足够长时间,它最终会终结于终身一代。
答案 1 :(得分:171)
Heap分为年轻代和老代,如下:
年轻一代:这是短期居住的地方,分为两个空间:
老一代:此池基本上包含终身和虚拟 (保留)空间,并将持有幸存的物体 在Young Generation收集垃圾后。
永久生成:此内存池名称也包含永久类元数据和描述符信息,因此PermGen空间始终为类保留,并且与类绑定,例如静态成员。
Java8更新: PermGen 替换为非常相似的 Metaspace 。
主要区别在于Metaspace动态地重新调整大小,即它可以在运行时扩展 Java Metaspace space:unbounded(默认)
代码缓存(虚拟或保留):如果您使用的是HotSpot Java VM,则其中包含代码缓存区域,其中包含将用于编译和存储本机代码的内存。
答案 2 :(得分:36)
年轻一代是什么?
Young Generation 是分配和老化所有新对象的地方。当年轻一代填满时,这会导致轻微的垃圾收集。很快就会收集到充满死亡物体的年轻一代。一些幸存的物体会老化并最终移动到老一代。
老一代是什么?
Old Generation 用于存储长期幸存的对象。通常,为年轻代对象设置阈值,并且当满足该年龄时,对象被移动到旧代。最终需要收集老一代。此事件称为主要垃圾回收
永久世代是什么?
Permanent generation 包含JVM描述应用程序中使用的类和方法所需的元数据。 JVM在运行时根据应用程序使用的类填充永久代。
自Java 8发布以来,PermGen已被Metaspace取代。
PermSize& MaxPermSize 参数现在将被忽略
三代人如何相互作用/相互联系?
图片来源& oracle technetwork教程文章:http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html
" 一般垃圾收集流程"上面的文章解释了它们与许多图表之间的相互作用。
查看摘要图表:
答案 3 :(得分:14)
Java虚拟机分为三代:年轻一代,老一代和永久一代。大多数对象最初都是在年轻一代中分配的。旧一代包含在一些年轻代集合中存活的对象,以及可能直接在旧代中分配的一些大对象。永久生成保存JVM方便垃圾收集器管理的对象,例如描述类和方法的对象,以及类和方法本身。
答案 4 :(得分:0)
SunHotSpot JVM中的内存分为三代:年轻一代,老一代和永久代。
仅供参考:永久基因不被视为Java堆的一部分。
三代人如何相互作用/相互联系? 对象(大型对象除外)首先分配给年轻一代。如果一个对象在x之后仍然存活。垃圾收集周期,它被提升到老/终身。因此,我们可以说年轻的一代包含短命的物体,而旧的一代则包含长寿命的物体。永久性的基因不与其他两代相互作用。