有一段时间,我的 Java 应用程序遇到了性能问题,我使用 JavaMelody 进行分析,不寻常的是“已用内存”图。它有很多短峰值,似乎很快就达到了 8GB 线,然后据我了解,GC 正在清理内存。有人有经验来追踪这些峰值的含义吗?似乎它们指出了一些具体问题。
GC和JVM配置为: -XX:PermSize=384m -XX:MaxPermSize=512m -XX:+UseCompressedOops -XX:+使用FastAccessorMethods -XX:+CMSClassUnloading启用 -XX:+UseParNewGC -XX:-使用ParallelOldGC -XX:-使用AdaptiveSizePolicy -XX:幸存者比率=128 -XX:新大小=4055m -XX:最大新尺寸=4055m -XX:+使用ConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=60 -XX:+使用CMSInitiatingOccupancyOnly -Xms12888m -Xmx12888m -Dsun.rmi.dgc.client.gcInterval=1800000 -Dsun.rmi.dgc.server.gcInterval=1800000
图表是(绿色是“平均值”,蓝色是“最大值”): Memory graph - 16:00 - 8:00 system without load, 8:00+ - system is under load
直到 8:00 系统都没有负载。
8:00 后,它处于负载状态,但负载不是很大(约 20 个同时操作)
最佳答案
这看起来像是您正在 Eden 空间中分配对象,这对于 JVM 来说是正常操作。我建议您使用内存分析器(例如 Flight Recorder)来了解分配率是多少,并看看是否有任何方法可以减少它。
特别是,如果您每隔几秒进行 GC 一次以上,我会尝试减少您创建的垃圾量。如果它比这个长,则取决于您的用例是否重要。
如果您最近没有做过内存分析,我建议您这样做,只是为了对您的应用程序有不同的看法。我发现即使性能不是问题,查找错误也很有用。
-XX:SurvivorRatio=128
这个值相当高,表明您有很多生命周期很短的对象。这些可能很容易优化掉。
我最近为纽约的客户开发了一个规则引擎,通过花一天时间降低分配率,我们将其性能提高了 2.3 倍。通过在 CPU 上花费第二天,我们将吞吐量提高了 4 倍。
关于Java: "used memory"图处频繁出现峰值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38053740/