我们在JBoss上运行一个基于Web Java的应用程序,允许的最大堆大小约为1.2 GB(总机器物理内存为2 GB)。在某些时候,应用程序停止响应(对客户端)几分钟。经过一些分析,我们发现罪魁祸首是Full GC。以下是详细GC日志的摘录:
74477.402:[Full GC [PSYoungGen:3648K-> 0K(332160K)] [PSOldGen:778476K-> 589497K(819200K)] 782124K-> 589497K(1151360K)[PSPermGen:102671K-> 102671K(171328K) )],646.1546860秒] [时间:用户= 3.84 sys = 3.72,真实= 646.17秒]
我不明白的是,在Full GC上花费的实时大约是11分钟(646秒),而用户+系统时间只有7.5秒。 7.5秒听起来花费更多的逻辑时间用于清洁< 200 MB来自老一代。所有其他时间去哪儿了?
非常感谢。
答案 0 :(得分:10)
所有其他时间去哪儿了?
您的应用程序很可能导致虚拟内存抖动。基本上,您的应用程序需要的虚拟内存页数远远多于可用于保存它们的物理页面。因此,它大部分时间都在等待从磁盘读取和写入vm页面。
有关详情,请参阅this wikipedia page。
解决方法是减少虚拟内存使用量或增加系统上的物理内存量。例如,您可以:
(但请注意,减少JVM堆大小可能是一把双刃剑。如果减少堆大小太多,应用程序将死于OutOfMemoryErrors,花费太多时间进行垃圾回收,或者遭受无法使用有效地缓存事物。)