Java堆术语:年轻的,老的和永久的世代?
我试图理解Java堆术语中年轻 , 老年和永久代的概念,尤其是三代之间的相互作用。
我的问题是:
- 年轻一代是什么?
- 老一辈是什么?
- 什么是永久的一代?
- 三代人如何互相交stream?
这似乎是一个常见的误解。 在Oracle的JVM中,永久代不是堆的一部分。 它是类定义和相关数据的独立空间。 在Java 6及更早的版本中,实际的string也存储在永久代中。 在Java 7中,internedstring存储在主对象堆中。
这是永久一代的好post 。
我喜欢JConsole的 Oracle 指南中给出的每个空间的描述:
对于HotSpot Java VM,用于串行垃圾收集的内存池如下所示。
- 伊甸园空间(堆):内存最初分配给大多数对象的池。
- 幸存者空间(堆):包含在伊甸园空间的垃圾收集中存活的对象的池。
- Tenured Generation(heap):包含已经存在一段时间的幸存者空间中的对象的池。
- 永久生成(非堆):包含虚拟机本身的所有reflection数据(例如类和方法对象)的池。 使用类数据共享的Java虚拟机,这一代分为只读和读写区域。
- 代码caching(非堆):HotSpot Java VM还包含代码caching,其中包含用于编译和存储本机代码的内存。
Java使用分代垃圾收集。 这意味着如果你有一个对象foo(它是某个类的实例),那么它存活的垃圾收集事件就越多(如果还有对它的引用),它就会被提升。 它始于年轻一代(本身被分成多个空间 – 伊甸园和幸存者),如果能长期存活下来,最终会终结在终身的一代。
堆分为如下的年轻和老一代:
年轻一代 :短期居住的地方,分为两个空间:
- 伊甸园空间 :当在这个空间分配新的关键字内存创build对象。
- 幸存者空间(Survivor Space) :这是包含从Eden空间收集java垃圾收集后存活的对象的池。
老一代 :这个游泳池基本上包含了终身和虚拟(保留)空间,并将持有年轻一代垃圾收集后存活的那些物体。
- 终身空间:这个内存池包含多个垃圾收集装置在幸存空间垃圾收集之后存活的多个垃圾收集对象之后存活的对象。
永久生成:这个内存池的名称也包含永久类的元数据和描述符信息,所以PermGen空间总是保留给类和那些绑定到类,例如静态成员。
Java8更新: PermGen被replace为非常相似的Metaspace 。
主要区别在于Metaspacedynamicresize,即可以在运行时扩展。
Java Metaspace空间:无界(默认)
代码高速caching (虚拟或保留):如果您使用的是HotSpot Java虚拟机,则包含代码caching区,其中包含将用于编译和存储本机代码的内存。
礼貌
年轻一代是什么?
年轻一代是所有新物体被分配和老化的地方。 当年轻一代填满时,这会导致轻微的垃圾收集。 一个充满死物的年轻一代很快就被收集起来。 一些幸存的物体老化,最终转移到老一代。
老一辈是什么?
老一代用来存放长期存活的物体。 典型地,为年轻一代的对象设置一个阈值,当这个年龄被满足时,该对象被移到老一代。 最终老一代需要收集。 这个事件被称为主要垃圾收集
什么是永久的一代?
永久代包含JVM所需的元数据,用于描述应用程序中使用的类和方法。 永久代由JVM在运行时根据应用程序使用的类来填充。
自Java 8发布以来,PermGen已经被Metaspace所取代。
PermSize和MaxPermSize参数现在将被忽略
三代人如何互相交stream?
Image source&oracle technetwork教程文章: http : //www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html
上面的文章“ 通用垃圾收集过程 ”解释了它们与许多图表之间的相互作用。
看看汇总图:
Java虚拟机分为三代:年轻一代,老一代和一代。 大多数物体最初分配给年轻一代。 旧一代包含了一些年轻一代collections的对象,以及一些可以直接分配到老一代的大对象。 永久代持有JVM发现方便垃圾收集器pipe理的对象,如描述类和方法的对象,以及类和方法本身。
这篇文章是一个很好的垃圾收集者调查。 它定义了垃圾收集的基本概念和术语,并包含许多说明图。 任何对自动内存分配工作感兴趣的人都是“必读” 阅读它会使你更容易阅读和理解别人指出的各种文件。
(这个文件所缺less的是有关垃圾收集者,特别是多核系统整个业务的1993年以后的研究的任何信息,但是,在学习运行之前,你必须学会走路。
假设您在讨论Sun JDK / OpenJDK,请参阅OpenJDK网站上的Storage Management页面 。 在底部有更多的信息链接。
虽然是关于调整我不能推荐这个文件看看第3章,如果你喜欢深入。
SunHotSpot JVM中的内存分为三代:年轻一代,老一代和永久代。
- 年轻一代:新创造的对象被分配给年轻的一代。
- 老一代:如果新的对象请求更大的堆空间,它会直接分配到旧的。 还有一些在GC循环中幸存下来的物体被提升到老根,也就是老根生活的物体。
- 永久生成:永久生成包含JVM发现的方便垃圾收集器pipe理的对象,如描述类和方法的对象,以及类和方法本身。
供参考:永久gen不被认为是Java堆的一部分。
三代人如何互相交stream? 对象(大型除外)首先分配给年轻一代。 如果一个对象在x之后仍然存在, 垃圾收集周期,它被提升到旧的/终身的。 因此,我们可以说,年轻的基因包含着短暂的物体,而旧的基因则包含着长寿命的物体。 永久的基因不与其他两代相互作用。