【发布时间】:2012-04-02 02:14:14
【问题描述】:
我正在测试一个用 Java 编写的 API,它有望最大限度地减少处理通过网络接收的消息的延迟。为了实现这些目标,我正在尝试各种可用的垃圾收集器。
我正在尝试四种不同的技术,它们利用以下标志来控制垃圾收集:
1) 序列号:-XX:+UseSerialGC
2) 并行:-XX:+UseParallelOldGC
3) 并发:-XX:+UseConcMarkSweepGC
4) 并发/增量:-XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode -XX:+CMSIncrementalPacing
我在五个小时内运行了每项技术。我定期使用 ManagementFactory.getGarbageCollectorMXBeans() 提供的 GarbageCollectorMXBean 列表来检索收集垃圾所花费的总时间。
我的结果?请注意,此处的“延迟”是“我的应用程序 + API 用于处理从网络中提取的每条消息所花费的时间。”
串行:789 个 GC 事件,总计 1309 毫秒;平均延迟 47.45 us,中值延迟 8.704 us,最大延迟 1197 us
并行:1715 个 GC 事件,总计 122518 毫秒;平均延迟 450.8 us,中值延迟 8.448 us,最大延迟 8292 us
并发:4629 个 GC 事件,总计 116229 毫秒;平均延迟 707.2 us,中值延迟 9.216 us,最大延迟 9151 us
增量:5066 次 GC 事件,总计 200213 毫秒;平均延迟 515.9 us,中值延迟 9.472 us,最大延迟 14209 us
我发现这些结果太不可能了,以至于近乎荒谬。有谁知道我为什么会得到这些结果?
哦,为了记录,我使用的是 Java HotSpot(TM) 64 位服务器虚拟机。
【问题讨论】:
-
您是否假设并行执行两件事必然比执行一件接一件的事情要快?
-
我预计最大延迟会上升
-
那么,在您的不同场景中,这 5 个小时内实际处理了多少条消息?您是在运行单线程还是多线程?
-
我每次处理 4.318 亿条消息。该应用程序使用两个线程——一个在关键路径上从线路上抓取消息并将它们打包到一个队列中。非关键路径上的将它们从队列中取出并放入优先队列中;然后,每秒一次,它会排空优先级队列并计算那一秒的中值/平均/最大/等延迟统计信息。这台机器有两个 6 核 Intel Xeon 5680s 和 24 GB RAM。