直接分配给Old Generation的巨大对象的大小

最近我一直在阅读Java中不同代的对象分配。 大多数时候,新对象在Eden(Young Generation的一部分)中分配,然后如果满足以下任何条件,它们将被提升为Old Generation。

(1)对象的年龄达到了终点
(2)当从伊甸园(或)另一个幸存者空间(从)复制对象时,幸存者空间(to)已满

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


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

谢谢你的时间 :)

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

这就是分配粗鲁的样子:

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

您可以使用以下标志设置限制

 XX:PretenureSizeThreshold=size 

它的默认值是0我假设默认情况下如果你没有设置它就不会考虑值= 0 ,这意味着默认情况下没有最大值作为阈值,默认情况下,对象仅基于提升而被提升GC存活数

HotSpot版本

 java version "1.7.0_45" Java(TM) SE Runtime Environment (build 1.7.0_45-b18) Java HotSpot(TM) 64-Bit Server VM (build 24.45-b08, mixed mode) 

获取所有vm选项(支持),您可以运行

 java -XX:+PrintVMOptions -XX:+AggressiveOpts -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+PrintFlagsFinal -version 

然后你可以参考hotspot vm选项文档或google特定选项(如果没有列出)


 byte[] array = new byte[300*1024*1024]; for(MemoryPoolMXBean memoryPoolMXBean: ManagementFactory.getMemoryPoolMXBeans()){ System.out.println(memoryPoolMXBean.getName()); System.out.println(memoryPoolMXBean.getUsage().getUsed()); } 

输出:

 $ java -Xmx1500m -Xms1500m -Xmn500m -XX:PretenureSizeThreshold=100000000 -XX:+PrintGCDetails JVMMemoryInspection Code Cache 393664 PS Eden Space 330301752 PS Survivor Space 0 PS Old Gen 0 PS Perm Gen 2749520 

JVM标志:

-Xms1G -Xmx1G -Xmn500m -XX:PretenureSizeThreshold = 100000000 -XX:+ PrintGCDetails

通过将年轻一代的大小固定为500MB,eden大约为384MB,因此任何大于384MB的对象都会直接进入OldGen,并且在Eden本身中分配的对象少于384MB。 您可以在下面找到生成用法

byte [] array = new byte [400 * 1024 * 1024];

 PSYoungGen total 448000K, used 30720K eden space 384000K, 8% used from space 64000K, 0% used to space 64000K, 0% used ParOldGen total 536576K, used 409600K object space 536576K, 76% used 

byte [] array = new byte [300 * 1024 * 1024];

  PSYoungGen total 448000K, used 337920K eden space 384000K, 88% used from space 64000K, 0% used to space 64000K, 0% used ParOldGen total 536576K, used 0K object space 536576K, **0% used** 

对于400MB分配,伊甸园使用率是8%,其中旧的使用率为76%对于300MB分配,伊甸园使用率为88%,而旧的使用率为0%因此很明显,所有尺寸大于伊甸园的对象将是直接分配到旧的。

感谢apangin和Jigar的宝贵见解:)
我认为-XX:根本没有考虑PretenureSizeThreshold。