我们有一个在我们的 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/