Java|Java:什么是Java中的分代垃圾收集?

Java|Java:什么是Java中的分代垃圾收集?

Java垃圾收集器实现了一种按年龄对对象进行分类的分代垃圾收集策略 。
必须标记和压缩JVM中的所有对象是低效的 。 随着越来越多的对象被分配 , 对象列表会增加 , 导致垃圾收集时间变长 。 应用程序的经验分析表明 , Java中的大多数对象都是短期的 。 这就是为什么Java将对象分类为几代 , 并相应地执行垃圾收集 。
年轻一代
新创建的对象始于年轻一代 。 年轻一代进一步细分为:
l 伊甸园空间—所有新对象都从这里开始 , 初始内存分配给它们
l 幸存者空间(FromSpace和ToSpace)—在经历了一个垃圾收集周期后 , 对象从伊甸园移到这里 。
当对象被年轻一代垃圾收集时 , 这是一个小的垃圾收集事件 。 当伊甸园空间充满对象时 , 将执行次要GC 。 所有死亡对象都被删除 , 所有活着的对象都被移动到一个幸存者空间 。 次要GC还检查幸存者空间中的对象 , 并将它们移动到另一个幸存者空间 。
以以下顺序为例:
1.伊甸园拥有所有对象(活的和死的)
【Java|Java:什么是Java中的分代垃圾收集?】2.小规模的垃圾收集—所有死亡对象都会从伊甸园中移除 , 所有活动对象都将移动到S1(FromSpace) , 伊甸园和S2现在是空的 。
3.新对象被创建并添加到伊甸园 , 伊甸园和S1中的一些物体已经死亡 。
4.小规模的垃圾收集—所有死亡对象都从伊甸园和S1中移除 , 所有活动对象都移动到S2(ToSpace) , 伊甸园和S1现在是空的 。
因此 , 在任何时候 , 一个幸存者空间总是空的 。 当幸存物体达到一定的移动阈值时 , 它们会移动到老一代 。 你可以使用-Xmn标志来设置年轻一代的大小 。

老一代
长寿物体最终会从年轻一代转移到老年一代 , 这也被称为“终身世代” , 它包含了在幸存者空间中停留很长时间的对象 。 为对象的使用期限定义了一个阈值 , 该阈值决定了在将其移到旧一代之前 , 它可以存活多少个垃圾收集周期 。
当对象从老一代被垃圾收集时 , 这是一个主要的垃圾收集事件 。 你可以使用-Xms和-Xmx标志来设置堆内存的初始大小和最大大小 。
由于Java使用了分代垃圾收集 , 对象存活的垃圾收集事件越多 , 它在堆中的提升就越大 。 它从年轻一代开始 , 如果存活时间足够长 , 最终会在终身制一代结束 。
请考虑以下示例 , 以了解对象在空间和代之间的升级:
当一个对象被创造时 , 它首先被放入年轻一代的伊甸园空间 。 一旦发生一次小的垃圾收集 , 来自伊甸园的活动对象将被提升到FromSpace 。 当下一次小垃圾收集发生时 , 来自伊甸园和FromSpace的活动对象将移动到ToSpace , 此循环持续特定次数 , 如果对象在这一点之后仍在使用 , 下一个垃圾收集周期将把它移到老一代空间 。
永久代
类和方法等元数据存储在永久代中 。 JVM在运行时根据应用程序使用的类填充它 , 不再使用的类可能会被永久生成垃圾收集 。 你可以使用-XX:PermGen和-XX:MaxPermGens标志来设置永久代的初始大小和最大大小 。
元空间
从Java 8开始 , 元空间内存空间取代了PermGen空间 。 实现与PermGen不同 , 堆的这个空间现在自动调整大小 , 这避免了由于堆的PermGen空间有限而导致应用程序内存不足的问题 。 元空间内存可以被垃圾收集 , 当元空间达到最大大小时 , 不再使用的类可以被自动清理 。