A use case for a manual GC invocation?

拈花ヽ惹草 提交于 2019-11-28 14:37:47

For low latency trading systems I use the GC in an atypical manner.

You want to avoid any collection, even minor ones during the trading day. A way to do this is to create less than 300 KB of garbage a second. This is around 1 GB per hour, or up to 24 GB per day. When you use a 24 GB Eden space it means there is no minor/major GCs. However to ensure a GC occurs at a time which is planned and acceptable, a System.gc() is called at say 5 AM each morning and you have a clean Eden space for the next day.

There are times, when you create more garbage than expected e.g. failing to reconnect to a data source, and you might get a small number of minor collections. However this only happens when something is going wrong.

For more details http://vanillajava.blogspot.co.uk/2011/06/how-to-avoid-garbage-collection.html

by avoiding garbage is not exactly trivial and makes the code harder to maintain.

Avoiding garbage entirely is near impossible. However 300 KB/s is not so hard for a JVM. (You can have more than one JVM these days on one machine with 24 GB Eden spaces)

Note if you can keep below 50 KB/s of garbage you can run all week with out a GC.

Periodically select a server, let no more requests be send to it, let it finished its running requests, let it do its GC, and re-activate the server.

You can treat a GC as a failure to meet your SLA condition. In this case you can remove a server when you determine this is about to happen from your cluster, Full GC it and return it to the cluster.

However, there are cases when the GC takes too long and avoiding long pauses

You have to distinguish between pauses caused by young-only, mixed/concurrent phase and full GCs.

In most cases it's the full GCs that you want to avoid while the other ones are acceptable, which can often be achieved with some GC-tuning and optimizing the code to avoid large allocation bursts.

In principle G1 should be able to run forever on young/mixed cycles and a full GC could be considered a soft failure. CMS can at least do so for many days with careful tuning, but may eventually succumb to fragmentation and require a full GC for compacting.

In cases where even the young GC pauses are not acceptable or garbage piles up too fast for the concurrent phase to handle with acceptable pause times then the strategy you outline may be a viable workaround.

Note that there also other use-cases for manually triggering GCs, such as GC-managed native resources, e.g. direct byte buffers, although those are fairly troublesome in general.

Also note that not all System.gc() calls are created equal, there is the ExplicitGCInvokesConcurrent option too.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!