java - 直接分配给老年代的巨大对象的大小

标签 java memory-management garbage-collection jvm objectsize

最近我一直在阅读有关 Java 中不同代的对象分配的内容。大多数情况下,新对象在 Eden(年轻代的一部分)中分配,然后如果满足以下任何条件,它们就会被提升到老年代。

(1) 对象的年龄达到了tenuring阈值
(2) 从 Eden(或)另一个幸存者空间(从)复制对象时,幸存者空间(to)已满

但也有一种特殊情况,对象直接在老年代分配,而不是从年轻代提升。当我们试图创建的对象很大(可能是几 MB 的数量级)时,就会发生这种情况。


有没有办法知道巨大/巨大物体的大小/限制?我知道 G1 垃圾收集器的巨大对象标准。我只想知道 Java 6 之前或之后的大小限制

感谢您的宝贵时间 :)

最佳答案

HotSpot JVM 可以在年轻代中分配的对象的最大大小几乎与 Eden 的大小一样大(YoungGen 减去两个 Survivor 空间)。

这就是分配的大致样子:

  1. 使用线程本地分配缓冲区 (TLAB),如果 tlab_top + size <= tlab_end
    这是最快的路径。分配只是 tlab_top 指针增量。
  2. 如果 TLAB 快满了,请在 Eden 中创建一个新的 TLAB,然后在新的 TLAB 中重试。
  3. 如果 TLAB 剩余空间不够,但仍然太大而无法丢弃,请尝试直接在 Eden 中分配对象。 Eden 中的分配也是使用原子操作的指针增量(eden_top + size <= eden_end),因为 Eden 在所有线程之间共享。
  4. 如果 Eden 中的分配失败,通常会发生次要收集。
  5. 如果在 Young GC 之后 Eden 中没有足够的空间,则会尝试直接在老年代进行分配。

关于java - 直接分配给老年代的巨大对象的大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24618467/

相关文章:

ios - 使用数据管理器单例管理核心数据对象

c++ - 更改自动分配内存的范围是否会影响性能?

algorithm - 如果没有垃圾收集,算法和/或数据结构的一些例子很难或不可能正确实现?

java - hudson 插件问题

java - 如何修复 Android 上 G+ 中的 boolean com.google.android.gms.common.ConnectionResult.hasResolution() Null 引用

java - 为什么 Spring 3 @Component 名称在具有不同包时会发生冲突?

java - 为原型(prototype) Maven 项目设置动态速度属性

android - Android 中使用的确切内存模型是什么?

java - 为数据密集型应用程序的 JVM 提供适当的堆和旧代大小

java - 垃圾收集器意外输出