垃圾收集如何影响码头延迟?

时间:2015-12-06 09:20:24

标签: java garbage-collection jvm jetty

我有一个码头应用程序每秒处理大约2k个请求。 Machine有8个内核,JVM堆大小为8GB。有很多内存映射文件和内部缓存,因此占用了大部分堆空间(4.5 GB)。

以下是应用程序稳定并且JVM完成调整Young和Old gen空间后的统计信息: 年轻一代:2.6GB 老一代:5.4GB

我看到我的年轻GC每隔3秒被调用一次,整个伊甸园空间被清除(即很少有数据传递给老一代)。我知道如此快速地填补Young一代意味着我分配了太多的对象并且这是一个问题。但是我的应用程序肯定没有内存泄漏,因为服务器已经运行了2周,没有OOM崩溃。

年轻的GC是世界事件的终点。所以我的理解是在这段时间内所有线程都暂停了。因此,当我从日志中监视延迟时,我可以看到每2-3秒约6-9个请求的响应时间大于&gt; 100ms(我的平均响应时间<10 ms)。当调用Full GC时,我看到6-9个请求的响应时间大于&gt; 3秒(那就是完整的GC需要多长时间,因为它的调用非常少,这不是问题)

我的问题是,由于我的jetty应用程序有一个200大小的线程池而且没有有界请求队列,不应该调用年轻的GC对我的响应时间有手风琴效果吗?是否会在队列中的所有请求中添加100毫秒的缓冲区?

如果是这样,衡量从添加到队列到输出响应的响应时间的最佳方法是什么?因为我上面提到的6-9请求是检查日志。基本上,当在响应发送之前调用应用程序逻辑时,我会维护开始和结束时间变量并减去这些变量并将其转储到日志中。

一种方法是检查我的负载均衡器。但由于这些服务器都在ELB之后,除了平均响应时间之外,我在这里没有多少访问权限,这对我来说并不是很有帮助。

1 个答案:

答案 0 :(得分:-1)

您应该为您的应用程序启用GC日志记录。尝试添加以下jvm命令行参数

-XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -XX:-PrintTenuringDistribution -XX:+PrintGCCause -XX:+PrintGCApplicationStoppedTime -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=<REPLACE_ME> -XX:GCLogFileSize=20M -Xloggc:<path_to_gc_log_dir>/gc.log

然后查看GC日志中的事件并尝试将其与应用程序日志相关联