自动将对象提升到老年代

Sam*_*ský 5 java memory garbage-collection object heap-memory

当一个对象达到Tenuring Threshold 或者当它被转移时“TO”生存空间已满时,它可以从年轻代提升到老年代。

因此,我的问题是:为了提高性能,如果我知道我的对象将被频繁使用(引用),是否可以在 Old/Permanent Generation 中自动/手动声明一个对象,以便不在Eden 中声明它会延迟Minor Garbage Collection的必要性,从而延迟“Stop The World”事件并提高应用程序性能

Mar*_*ger 4

一般来说:

否 - 不适用于特定的单个对象。

更详细地说:

分配大致如下:

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

“黑客”:

参数如下:

XX:PretenureSizeThreshold=size
Run Code Online (Sandbox Code Playgroud)

该参数默认设置为0,因此被禁用。如果设置,它定义了自动分配到老年代的对象的大小阈值。

但:

您应该谨慎使用此参数:错误设置此参数可能会极大地改变您的 GC 行为。并且:只有百分之几的对象在第一次 GC 中幸存下来,因此大多数对象不必在年轻 GC 期间进行复制。

因此,年轻 GC 非常快,您实际上不需要通过强制将对象分配到老年代来“优化”它。

Java参数:

如果您想了解可能的 Java 参数的概述,请运行以下命令:

java -XX:+PrintVMOptions -XX:+AggressiveOpts -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+PrintFlagsFinal  -version
Run Code Online (Sandbox Code Playgroud)

这将打印您可以设置的所有标志。

不同的垃圾收集器:

另请记住,存在不同的垃圾收集器,并且计划Java 9应使用垃圾优先 (G1) GC作为默认垃圾收集器,这可能会以不同的方式处理大对象(通过将它们分配到人类区域中) 。

附加来源:

堆栈溢出问题:直接分配给老年代的巨大对象的大小