java - 为什么让短期和长期对象在垃圾收集中有所不同?

标签 java garbage-collection

我经常读到,在 Sun JVM 中,短期对象(“相对较新的对象”)可以比长期对象(“相对较旧的对象”)更有效地进行垃圾收集

  • 为什么会这样?
  • 这是特定于 Sun JVM 还是源于一般垃圾收集原则?

最佳答案

大多数 Java 应用程序会创建 Java 对象,然后很快将其丢弃,例如。您在方法中创建了一些对象,然后一旦退出该方法,所有对象都会消失。大多数应用程序都以这种方式运行,并且大多数人倾向于以这种方式编写应用程序。 Java 堆大致分为 3 部分,永久、老(长生命周期)代和年轻(短生命周期)代。 Young gen 进一步分为 S1、S2 和 eden。这些只是堆。

大多数对象都是在年轻一代中创建的。这里的想法是,由于对象的死亡率很高,我们快速创建它们,使用它们然后丢弃它们。速度至关重要。当你创建对象时,young gen 会被填满,直到发生 Minor GC。在次要 GC 中,所有存活的对象都从 eden 复制过来,并将 S2 复制到 S1。然后,“指针”停留在 eden 和 S2 上。

每个副本都会使对象老化。默认情况下,如果一个对象存在 32 个副本,即。 32 次次要 GC,然后 GC 估计它会存在更长的时间。因此,它所做的就是通过将其移至老一代来对其进行终身维护。老一代只是一个大空间。当老一代填满时,老一代会发生一次完整的 GC 或主要 GC。因为没有其他空间可以复制,GC 必须压缩。这比 Minor GC 慢很多,这就是我们避免更频繁地这样做的原因。

您可以使用

调整tenuring参数
java -XX:MaxTenuringThreshold=16 

如果你知道你有很多长寿的对象。您可以使用

打印应用程序的各个年龄段
java -XX:-PrintTenuringDistribution

关于java - 为什么让短期和长期对象在垃圾收集中有所不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2620533/

相关文章:

garbage-collection - Racket 中的尾调用优化

.NET 应用程序因 GC 线程死锁而挂起

java - gc 堆分配和我的 java 程序之间的比率

java - SLF4J Java 日志记录设计

java - 使用 JSch 从 SSH 服务器读取命令输出时获取不需要的字符

java - DynamoDB DynamoDBAutoGenerateStrategy.CREATE 不适用于 DynamoDBMapperConfig.SaveBehavior.UPDATE_SKIP_NULL_ATTRIBUTES

java - 一个类中的事件可以触发另一个类中的操作吗?

java - 正则表达式:如何知道字符串至少包含 2 个大写字母?

Java循环引用,糟糕的风格?

spring-boot - spring boot 2 actuator jvm.gc.memory.allocated 公制