我在生产中遇到了一个奇怪的问题,经过 5 年多的运营,只发生过一次。我们发现 PSPermGen 和“真实”持续时间远高于用户+系统时间。2016 年 2 月 4 日,PSPermGen 耗时 38.96 秒,而之前的运行时间为 0.2-0.3 秒,并且没有释放内存。当 user+sys 为 0.3-0.4 秒时,实时耗时 40 秒,与之前的运行相比异常高。Full GC 没有频繁发生,我也没有观察到任何与 GC 相关的错误。在整个持续时间内,CPU 使用率 < 1%,内存使用率 < 20%。
信息 | 虚拟机 1 | 2016/02/04 02:56:56 | [GC [PSYoungGen: 88312K->936K(86144K)] 261016K->174219K(260928K), 0.4070215 秒] [时间: user=0.75 sys=0.00, real=0.42 secs] 信息 | 虚拟机 1 | 2016/02/04 02:57:08 | [GC 信息 | 虚拟机 1 | 2016/02/04 02:57:11 | [PSYoungGen: 85703K->96K(102400K)] 258985K->175019K(278784K), 3.1902546 secs] [Times: user=7.14 sys=0.05, real=3.18 secs] INFO | 虚拟机 1 | 2016/02/04 02:57:13 | [GC [PSYoungGen: 102368K->755K(123520K)] 277291K->175700K(299904K), 0.0266474 秒] [时间: user=0.00 sys=0.00, real=0.02 secs] INFO | 虚拟机 1 | 2016/02/04 02:57:20 | [GC [PSYoungGen: 123507K->128K(144768K)] 298452K->175419K(321152K), 0.0021357 秒] [时间: user=0.01 sys=0.01, real=0.02 secs] INFO | 虚拟机 1 | 2016/02/04 02:57:28 | [GC [PSYoungGen: 143616K-> 977K(144704K)] 318907K->176319K(321088K),0.0035773 秒] [时间:用户=0.00 系统=0.00,实际=0.00 秒] 信息 | 虚拟机 1 | 2016/02/04 02:57:28 | [完整 GC 状态 | 包装 | 2016/02/04 02:58:03 | JVM 出现挂起:等待来自 JVM 的信号超时。重新启动 JVM。信息 | 虚拟机 1 | 2016/02/04 02:58:08 | [PSYoungGen: 977K->0K(144704K)] [PSOldGen: 175341K->35127K(174784K)] 176319K->35127K(319488K) [PSPermGen: 38992K->38992K(65536K) ], 38.9595115 secs] [Times: user=0.33 sys=0.14, real=40.07 secs ]
执行的最后几个完整 GC 是:
信息 | 虚拟机 1 | 2016/02/02 12:59:49 | [全 GC [PSYoungGen: 433K->0K(98944K)] [PSOldGen: 176749K->38591K(174784K)] 177183K->38591K(273728K) [PSPermGen: 39380K->39380K(65536K)], 0.2982459Ts] :用户=0.30 系统=0.00,真实=0.30 秒] 21189 信息 | 虚拟机 1 | 2016/02/03 03:15:16 | [完整 GC [PSYoungGen: 2873K->0K(125696K)] [PSOldGen: 171318K->33804K(174784K)] 174191K->33804K(300480K) [PSPermGen: 39940K->38366K(65536K)], 0.331780T 秒] :用户=0.34 系统=0.00,真实=0.34 秒] 47151 信息 | 虚拟机 1 | 2016/02/03 12:16:51 | [Full GC [PSYoungGen: 1406K->0K(171776K)] [PSOldGen: 174936K->38003K(174784K)] 176342K->38003K(346560K) [PSPermGen: 38642K->38642K(65536K)], 0.298882T 秒] : user=0.30 sys=0.00, real=0.30 secs]
我在大约 8GB 和 4 个 CPU 的 Windows 2003 x86 上运行 Java 6 update 45。磁盘空间绰绰有余。我们将 JVM 配置为 256 MB 的初始堆内存和 512 MB 的最大内存。该应用程序通过 Tanuki Wrapper 作为 Windows 服务运行。
目前看来,长时间的 GC 暂停似乎不是由于内存、CPU、磁盘空间等原因。我在这里缺少什么?