我对Heap,Young,Tenured和Perm一代感到困惑。
有人可以解释一下吗?
答案 0 :(得分:71)
Java垃圾收集器称为 Generational Garbage Collector 。应用程序中的对象可以使用不同的时间长度,具体取决于它们的创建位置和使用方式。这里的关键见解是对短寿命和长寿命对象使用不同的垃圾收集策略允许GC针对每种情况进行专门优化。
松散地说,当对象“幸存” Young Generation 中的重复垃圾收集时,它们会迁移到 Tenured Generation 。 永久生成是一种特殊情况,它包含JVM所需的对象,这些对象不一定在程序中表示,例如表示类和方法的对象。
由于 Young Generation 通常会包含大量垃圾,因此它会针对一次性清除大量未使用的对象进行优化。 Tenured Generation 因为它包含更长寿命的对象,因此可以快速收集垃圾,而不会浪费大量内存。
随着垃圾收集技术的改进,细节变得非常复杂,并且取决于您的JVM及其配置方式。如果您需要确切知道发生了什么,您应该阅读正在使用的特定JVM的documentation。
也就是说,有一个简单的历史安排,这在概念层面仍然有用。从历史上看, Young Generation 将是copy collector,而 Tenured Generation 将是mark and sweep collector。 复制收集器基本上不需要花费掉除垃圾的CPU成本,大部分成本是维护活动对象,这种效率的代价是更大的内存使用量。 标记和扫描收集器为实时和未使用的对象支付一些CPU成本,但更有效地利用内存。
答案 1 :(得分:28)
Java堆内存是操作系统分配给JVM的内存的一部分。每当我们创建对象时,它们都是在heap in java内创建的。
为了垃圾收集,Java堆空间分为三个区域或一代,称为 Young Generation,Old or tenured Generation和Permanent Generation 。永久生成在热点JVM中的完整gc期间被垃圾收集
Young Generation 是分配和老化所有新对象的地方。当年轻一代填满时,这会导致轻微的垃圾收集。很快就会收集到充满死亡物体的年轻一代。一些幸存的物体会老化并最终移动到老一代。
老一代 用于存储长期幸存的对象。通常,为年轻代对象设置阈值,并且当满足该年龄时,对象被移动到旧代。最终需要收集老一代。此事件称为主要垃圾回收。
永久代 包含JVM描述应用程序中使用的类和方法所需的元数据。 JVM在运行时根据应用程序使用的类填充永久代。
自Java 8发布以来,PermGen 已被 Metaspace 取代。 PermSize& MaxPermSize 参数现在将被忽略。看看 Pierre - Hugues Charbonneau的dzone article来了解Metaspace 。
图片来源:http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html
有关详细信息,请参阅同一篇文章。
答案 2 :(得分:7)
堆中的所有对象在被引用时都会存活。当它们不再存在时,垃圾收集器(GC)将回收它们的记忆。
PermGen,Young和Tenured是对象的不同分类(或堆中的空间)。
PermGen:这些对象将永远存在,它们不会被垃圾收集。类对象在那里,实习字符串等。我不知道那里是否有GC(当系统UNloads类......但这不正常)
年轻:创建对象时就在这里。
Tenured:当一个对象在N GC传递中存活时会进入此分类/类别(幸存= GC传递但该对象被引用,因此无法回收)。
根据使用的GC和一些参数化,GC或多或少地通过。
然后,垃圾收集可以使用不同的方法来填充堆中的对象。这种对象分类有助于实现它。
答案 3 :(得分:2)
这是另一篇关于如何调整/调整GC参数的优秀(尽管很长)文章,这可能有助于您了解更多:
https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/
如果您遇到GC问题并且需要知道如何阅读GC日志,或者需要了解当前GC收集器的工作原理,那么这是非常有用的读物。
如果要挂接正在运行的系统的远程监控以查看实时内存使用情况和GC运行,请检查此工具: