【发布时间】:2016-03-11 00:13:48
【问题描述】:
我有一个码头应用程序每秒处理大约 2k 个请求。机器有 8 个内核,JVM 堆大小为 8GB。有很多内存映射文件和内部缓存,因此占用了大部分堆空间(4.5 GB)。
以下是应用程序稳定并且 JVM 完成对 Young 和 Old gen 空间的调整后的统计数据: 年轻一代:2.6GB 老一代:5.4GB
我看到我的年轻 GC 每 3 秒被调用一次,并且整个 Eden 空间都被清除(即传递给老年代的数据非常少)。我知道这么快填满年轻一代意味着我分配了太多的对象,这是一个问题。但是我的应用程序中绝对没有内存泄漏,因为服务器自 2 周以来一直在运行,没有出现 OOM 崩溃。
Young GC 是一项停止世界赛事。所以我的理解是在这段时间内所有线程都暂停了。因此,当我从日志中监控延迟时,我可以看到每 2-3 秒大约有 6-9 个请求的响应时间 > 100 毫秒(我的平均响应时间小于 10 毫秒)。当调用 Full GC 时,我看到 6-9 个请求的响应时间 > 3 秒(这就是 Full GC 需要的时间,因为它被调用的次数非常少,所以这里不是问题)
我的问题是,既然我的码头应用程序有一个 200 大小的线程池并且没有有界的请求队列,那么调用年轻 GC 不应该对我的响应时间产生手风琴效应吗?是否会为队列中的所有请求添加 100 毫秒的缓冲区?
如果是这样,衡量从添加到队列到输出响应的响应时间的最佳方法是什么?因为我上面提到的 6-9 请求是来自检查日志。所以基本上,在发送响应之前调用应用程序逻辑时,我会维护开始和结束时间变量,然后减去这两个变量并将其转储到日志中。
一种方法是检查我的负载平衡器。但由于这些服务器位于 ELB 后面,除了对我没有帮助的平均响应时间之外,我在这里并没有太多访问权限。
【问题讨论】:
标签: java garbage-collection jvm jetty