如何说服Java垃圾收集器在工作集小时运行? [英] How to convince Java Garbage Collector to run when working set is small?

查看:98
本文介绍了如何说服Java垃圾收集器在工作集小时运行?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是又一个请告诉我如何强制Java垃圾收集器运行的问题。在我们的应用程序中,我相信我们有很好的理由这样做。



这是一个服务器应用程序,通常有大约500万个活动对象。每5分钟一次,我们执行一个需要大约60秒的分析任务。如果在分析运行时触发完整的GC,则会有大约400万个活动对象。分析完成后,额外的35M对象将变为垃圾。服务器必须始终保持对请求的响应(即使在分析运行时)。



我们发现完整的GC需要大约1.5秒,如果分析没有运行,但分析运行时约15秒。不幸的是,我们的分配模式是这样的:即使分析仅在20%的时间内运行,全分析通常会在分析过程中触发。 (每第三次或第四次分析运行都会触发完整的GC。)



在开始分析运行之前,我添加了代码以调用备受嘲讽的System.gc(),if老一代的自由空间低于一定的阈值(5GB)。好处是非常可观的:我们获得了1.5秒的停顿时间,而不是15秒的停顿时间,我们为讨价还价释放了更多的垃圾。但是,有时System.gc()调用会被忽略,当GC自动触发时,几分钟后停止15秒。



我的问题,那么:有什么我们可以做的更强烈地说服垃圾收集器运行?我们正在运行1.7.0_09-icedtea并使用并行GC。我希望(a)手动强制垃圾收集的可靠方法,或者(b)调整收集器的某种方式,以便它做出更智能的自动决策。 (b)看起来很难,因为我不清楚收藏家是如何发现我们的工作组在这种戏剧性的时尚方面有所不同的。

我愿意诉诸实质hackery如果需要的话;这对我们来说是一个严重的问题。 (我们可能会将CMS或G1压缩器视为替代品,但我对CMS的吞吐量的影响持怀疑态度,并且G1被称为在我们使用的大字节数组面前表现不佳。)



附录:在生产中,我们目前的经验是System.gc()通常会触发完整的垃圾收集;至少在我们称之为的情况下。 (我们每10到30分钟只调用一次,堆有点但没有完全填充垃圾。)能够更可靠地触发垃圾回收会很好,但它在大多数情况下帮助我们。

b
$ b

在非面向用户的过程中单独运行数据分析,以便面向用户的服务器始终保持响应。我假设定期分析会生成某种摘要或结果数据;通过将其发送到面向用户的服务器以供最终用户使用,以便可以从那里提供服务,或者让您的前端从分析服务器单独获取。


This is yet another "please tell me how to force the Java garbage collector to run" question. In our application, I believe we have good reasons for doing this.

This is a server application, which typically has around 5M live objects. Once every 5 minutes, we perform an analysis task which takes ~60 seconds. If a full GC is triggered while the analysis is running, there will be around 40M live objects. The extra 35M objects become garbage when the analysis completes. The server must remain responsive to requests at all times (even while the analysis is running).

We've found that a full GC takes around 1.5 seconds if invoked when the analysis is not running, but around 15 seconds while the analysis is running. Unfortunately, our allocation pattern is such that full GCs usually trigger during the analysis, even though the analysis is only running 20% of the time. (Every third or fourth analysis run triggers a full GC.)

I added code to call the much-scorned System.gc() just before beginning an analysis run, if free space in the old generation is below a certain threshold (5GB). The benefit was very substantial: we're getting 1.5 second pause times instead of 15 second pause times, and we free more garbage into the bargain. However, sometimes the System.gc() call is ignored, and we wind up with a 15-second pause a few minutes later when the GC is triggered automatically.

My question, then: is there something we can do to more strongly convince the garbage collector to run? We're running 1.7.0_09-icedtea and using the Parallel GC. I'd like either (a) a reliable way to manually force garbage collection, or (b) some way to tune the collector so that it makes a more intelligent automatic decision. (b) seems hard, as it's not clear to me how the collector could detect that our working set varies in this dramatic fashion.

I'm willing to resort to substantial hackery if need be; this is a serious issue for us. (We might look into the CMS or G1 compactors as alternatives, but I'm leery of the throughput impact of CMS, and G1 is reputed to behave poorly in the face of large byte arrays, which we use.)

addendum: In production, our experience so far has been that System.gc() usually does trigger a full garbage collection; at least, under the situations where we're calling it. (We only call it once every 10 to 30 minutes, with the heap somewhat but not completely filled with garbage.) It would be nice to be able to trigger garbage collection more reliably, but it is helping us most of the time.

解决方案

Your problem is that you're running two applications with entirely different requirements and memory profiles in the same JVM.

Run the data analysis separately, in a non-user-facing process, so that the user-facing server remains constantly responsive. I assume the periodic analysis generates a summary or result data of some kind; make that available to end users by shipping it across to the user-facing server so it can be served from there, or else let your front end fetch it separately from the analysis server.

这篇关于如何说服Java垃圾收集器在工作集小时运行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆