java - Java 垃圾收集器的行为是随时间演变还是受到 JIT 的影响?

标签 java garbage-collection jvm jit

我们有一个在我们的 Intranet 上运行的生产 Web 应用程序:

  • 每天 0300 重新启动以执行其数据库备份
  • 在整个工作日(0800 到 1700)都有相同的负载
  • 在 Java HotSpot(TM) 64 位服务器虚拟机版本 20.45-b01 上运行
  • 在具有 16 个内核和 32 GB RAM 的物理机上运行,​​运行 Linux 2.6.18-128.el5
  • 不与任何其他重要进程共享机器
  • 配置为:

    -Xms2g
    -XX:PermSize=256m
    -Xmx4g
    -XX:MaxPermSize=256m
    -Xss192k
    -XX:+UseParNewGC
    -XX:+UseConcMarkSweepGC
    -XX:+CMSParallelRemarkEnabled
    -XX:CMSInitiatingOccupancyFraction=50
    -XX:+DisableExplicitGC
    

每天的堆使用情况:

  • 从启动到 0800 逐渐上升到 90%
  • 保持在 90% 直到 0930
  • 从 0930 到 1415 保持在 70%
  • 在 1415 时下降到 50%
  • 在 1445 时下降到 37%

此时,堆在大约 40 分钟内上升到 55%,然后回收到 37%,无限循环直到下一次重启。

我们在 JVM 上安装了 AppDynamics,可以看到 Major Garbage Collections 大约每分钟发生一次,对内存没有太大影响(当然除了上面概述的下降),直到内存达到 37%,当 Major 收集变得不那么频繁了。

Web 应用程序的行为显然有数百个外部因素,但研究的一个途径是,当 JVM 停止时,Hotspot JIT 信息显然会丢失。

是否有 GC 优化等也会随着 JVM 的关闭而丢失?由于某些 Hotspot 优化尚未发生,JVM 是否有效地消耗了比其需要更多的内存?

如果 JVM 没有重新启动并且我们找到了另一种方法来执行数据库备份,我们是否有可能从这个应用程序中获得更好的内存性能?

(重申一下,我知道有十万种因素可以影响应用程序的行为,尤其是几乎没有人知道的应用程序!我真的只是想知道是否有某些事情与JVM 停止时丢失的内存性能)

最佳答案

是的,由于 JIT 优化,GC 的行为可能会随着时间的推移而改变。一个例子是“逃逸分析”,它自 Java 6u23 以来默认启用。这种类型的优化可以防止在堆中创建某些对象,因此根本不需要垃圾收集。

有关详细信息,请参阅 Java 7's HotSpot Performance Enhancements .

关于java - Java 垃圾收集器的行为是随时间演变还是受到 JIT 的影响?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20975043/

相关文章:

java - 在 libgdx 中更改为游戏结束屏幕

java - 如何从ArrayList中一一返回

hadoop - 如何为 Apache Hadoop NameNode 启用 GC 日志记录,同时防止日志文件覆盖和限制磁盘空间使用

scala - Scala 中固有层次结构中的对象初始化序列

java - 从 java 命令行禁用 sap jco 跟踪

java - 按 ArrayList<Integer> 中的第三个元素对 ArrayList<ArrayList<Integer>> 进行排序

java - java中数组列表值相乘

c# - GC Roots 误解?

java - 我应该(可以吗?)我重写 Robot 类以通过重复的屏幕捕获节省内存,或者 GC 是否足够好?

java - 在没有 JRuby 和 Java 的情况下从 Ruby 访问 JMX