【发布时间】:2013-05-16 15:35:41
【问题描述】:
我有一个 Java 客户端,它消耗来自服务器的大量数据。如果客户端没有以足够快的速度跟上数据流,则服务器断开套接字连接。我的客户每天断开连接几次。我运行 jconsole 来查看内存使用情况,堆空间图看起来像一个定义相当明确的锯齿模式,在大约 0.5GB 和 1.8GB 之间波动(分配了 2GB 堆空间)。但是每次我断开连接都是在一个完整的 GC 期间(但不是在每个完整的 GC 上)。我看到完整的 GC 平均需要 1 秒多一点。根据一天中的时间,Full GC 在忙碌时每 5 分钟发生一次,或者在慢速期间 Full GC 之间最多可以间隔 30 分钟。
我怀疑如果我可以减少完整的 GC 时间,客户端将能够更好地跟上传入的数据,但我对 GC 调优没有太多经验。有没有人知道这是否是一个好主意,以及如何去做?或者是否有其他的想法也可以奏效?
** 更新 ** 我使用了 -XX:+UseConcMarkSweepGC 并且它有所改善,但在非常忙碌的时候我仍然断开连接。所以我将堆分配增加到 3GB 以帮助度过忙碌的时刻,现在它似乎运行得很好,但只有 1 天没有断开连接。也许如果我有时间,我会尝试减少产生的垃圾量,我相信这也会有所帮助。谢谢大家的建议。
【问题讨论】:
-
你能改变连接的超时时间吗?
-
将堆大小增加到 4GB 并观察断开模式和 Full GC 时间段。
-
不幸的是,更改断开连接阈值不是一种选择
-
我在 Java 服务器应用程序中看到的一件事是每次网络读取和复制都使用一个新对象。尝试更改为使用单字节数组分配进行读取并将字节从那里复制到其他持久字节数组。当然,我对 Java 最不满意的地方之一是大多数人使用代码库,这使得实际上无法进行这些更改,因为它被埋得太深了。
标签: java performance garbage-collection