最近我一直在阅读有关 Java 中不同代的对象分配的内容。大多数情况下,新对象在 Eden(年轻代的一部分)中分配,然后如果满足以下任何条件,它们就会被提升到老年代。
(1) 对象的年龄达到了tenuring阈值
(2) 从 Eden(或)另一个幸存者空间(从)复制对象时,幸存者空间(to)已满
但也有一种特殊情况,对象直接在老年代分配,而不是从年轻代提升。当我们试图创建的对象很大(可能是几 MB 的数量级)时,就会发生这种情况。
有没有办法知道巨大/巨大物体的大小/限制?我知道 G1 垃圾收集器的巨大对象标准。我只想知道 Java 6 之前或之后的大小限制。
感谢您的宝贵时间 :)
最佳答案
HotSpot JVM 可以在年轻代中分配的对象的最大大小几乎与 Eden 的大小一样大(YoungGen 减去两个 Survivor 空间)。
这就是分配的大致样子:
- 使用线程本地分配缓冲区 (TLAB),如果
tlab_top
+size
<=tlab_end
这是最快的路径。分配只是tlab_top
指针增量。 - 如果 TLAB 快满了,请在 Eden 中创建一个新的 TLAB,然后在新的 TLAB 中重试。
- 如果 TLAB 剩余空间不够,但仍然太大而无法丢弃,请尝试直接在 Eden 中分配对象。 Eden 中的分配也是使用原子操作的指针增量(
eden_top
+size
<=eden_end
),因为 Eden 在所有线程之间共享。 - 如果 Eden 中的分配失败,通常会发生次要收集。
- 如果在 Young GC 之后 Eden 中没有足够的空间,则会尝试直接在老年代进行分配。
关于java - 直接分配给老年代的巨大对象的大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24618467/