引起GC一致性改变的技术 [英] Techniques for causing consistent GC Churn

查看:110
本文介绍了引起GC一致性改变的技术的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找基准测试如何执行,同时争夺大量正在进行的垃圾回收。我之前曾经以稳定的单线程运行为基准测试了它的行为,现在我想在更强调的JVM中进行相同的测试;本质上我想有后台线程以合理的一致的速度创建和销毁对象。



我正在寻找关于如何实现稳定但GC密集型的建议操作。它需要完成以下几个目标:


  • 在GC中花费大量时间(如20-50%)
  • 随着时间的推移执行大致一致的工作量,并为GC创建类似的一致工作量

  • 避免填充堆并触发 Java堆空间错误

  • 避免重载GC并触发 超出GC开销限制 错误


解决方案

我实现了自己的pass,可以导致稳定的垃圾回收量。完整的代码可在这里找到: https://bitbucket.org/snippets/dimo414/argzK

肉是这两种方法,它们在给定的实时时间内(与线程时间或CPU时间相对)构造并释放大量对象:

  / ** 
*在列表图上循环,快速添加和删除元素
*导致GC,runFor秒,或直到线程
*终止。
* /
@Override
public void run(){
HashMap< String,ArrayList< String>> map = new HashMap<>();

long stop = System.currentTimeMillis()+ 1000l * runFor;
while(runFor == 0 || System.currentTimeMillis()< stop){
churn(map);


$ b $ **
*三个步骤来搅动垃圾收集器:
* 1.从地图
* 2.从地图中的列表中移除字符串的流失%
*填充列表备份至大小
* 3.填充地图返回至大小
* @param map
* /
protected void churn(Map< String,ArrayList< String>> map){
removeKeys(map);
churnValues(地图);
addKeys(map);

该类实现 Runnable 所以你可以在它自己的后台线程中启动它(或者同时启动几个)。它会运行,只要你指定,或者如果你喜欢,你可以启动它作为一个守护线程(所以它不会停止JVM终止),并指定它永远运行, 0 秒作为构造函数参数。






我做了一些这个类的基准测试,发现它接近三分之一的时间阻塞(推测在GC上),并确定了15-25%的流失和约500的大小的近似最优值。每次运行都进行了60秒,下面的图表绘制了线程时间,由 java.lang.managment.ThreadMXBean.getThreadCpuTime()报告,总字节数由线程分配,由 com.sun.management.ThreadMXBean.getThreadAllocatedBytes()





控制权(0%流失)shouldn基本上没有引入任何GC,我们可以看到它几乎不分配任何对象,并且几乎100%的时间花在线程中。从5%到95%的客户流失率,我们看到大约三分之二的时间花费在线程中,据推测另外三分之一用于GC。我想说,合理的百分比。有趣的是,在流失率非常高的时候,我们看到更多的时间用在了线程中,可能是因为GC正在清理这么多,它实际上可以更高效。看起来大约有20%是每个周期都会搅动的很多对象。





这绘制了线程在地图和列表的不同目标大小下的功能,我们可以看到随着大小的增加时间必须花在GC上,有趣的是我们实际上最终会分配更少的对象,因为更大的数据大小意味着它无法在同一时间内创建更多的循环。由于我们有兴趣优化JVM必须处理的GC流失量,因此我们希望它需要处理尽可能多的对象,并尽可能在工作线程中花费很少的时间。看起来大约4-500是一个很好的目标大小,因为它会产生大量的对象,并在GC中花费大量时间。



所有这些测试是用标准的 java 设置完成的,所以玩这个堆可能会导致不同的行为 - 特别是〜2000是堆填满前我可以设置的最大大小,如果我们增加了堆的大小,可能我们会看到更大尺寸的更好结果。


I'm looking to benchmark how something performs while contending with a high amount of ongoing garbage collection. I've previously benchmarked how it behaves in a stable, single-threaded run, and I'd now like to do the same tests in a more stressed JVM; essentially I'd like to have background threads creating and destroying objects at a reasonably consistent pace.

I'm looking for suggestions on how to implement a stable yet GC-intensive operation. It needs to accomplish several goals:

  • Spend a decent amount (say, 20-50%) of time in GC
  • Do an approximately consistent amount of work over time, and create a similarly consistent amount of work for the GC
  • Avoid flooding the heap and triggering a Java heap space error
  • Avoid overloading the GC and triggering a GC overhead limit exceeded error

解决方案

I implemented my own pass at something that could cause a stable amount of garbage collection. The full code is available here: https://bitbucket.org/snippets/dimo414/argzK

The meat is these two methods, which construct and release a large number of objects for a given period of real time (as opposed to thread time or CPU time):

/**
 * Loops over a map of lists, adding and removing elements rapidly
 * in order to cause GC, for runFor seconds, or until the thread is
 * terminated.
 */
@Override
public void run() {
    HashMap<String,ArrayList<String>> map = new HashMap<>();

    long stop = System.currentTimeMillis() + 1000l * runFor;
    while(runFor == 0 || System.currentTimeMillis() < stop) {
        churn(map);
    }
}

/**
 * Three steps to churn the garbage collector:
 *   1. Remove churn% of keys from the map
 *   2. Remove churn% of strings from the lists in the map
 *      Fill lists back up to size
 *   3. Fill map back up to size
 * @param map
 */
protected void churn(Map<String,ArrayList<String>> map) {
    removeKeys(map);
    churnValues(map);
    addKeys(map);
}

The class implements Runnable so you can start it (or several at once) in its own background thread. It will run for as long as you specify, or if you prefer you can start it as a daemon thread (so it doesn't stop the JVM from terminating) and specify it to run forever with 0 seconds as the constructor argument.


I did some benchmarking of this class and found it spent close to a third of its time blocking (presumably on GC) and identified approximate optimal values of 15-25% churn and a size of ~500. Each run was done for 60 seconds, and the graphs below plot the thread time, as reported by java.lang.managment.ThreadMXBean.getThreadCpuTime() and the total number of bytes allocated by the thread, as reported by com.sun.management.ThreadMXBean.getThreadAllocatedBytes().

The control (0% churn) shouldn't introduce essentially any GC, and we can see it allocates hardly any objects and spends nearly 100% of its time in the thread. From 5% up to 95% churn we see fairly consistently about two thirds of the time is spent in thread, presumably the other third is spent in GC. A reasonable percentage, I'd say. Interestingly, at the very high end of the churn percentage we see more time being spent in the thread, presumably because the GC is cleaning up so much, it's actually able to be more efficient. It seems around 20% is a good number of objects to be churning each cycle.

This plots how the thread functions at different target sizes for the map and lists, we can see as the size increases more time must be spent in GC, and interestingly we actually end up allocating fewer objects, as the larger data size means it's unable to make as many loops in the same period of time. Since we're interested in optimizing the amount of GC churn the JVM has to deal with, we want it to need to deal with as many objects as possible, and spend as little time as possible in the working thread. It seems around 4-500 is a good target size, therefore, as it generates a large number of objects and spends a good amount of time in GC.

All these tests were done with the standard java settings, so playing with the heap may cause different behavior - in particular, ~2000 was the maximum size I could set before the heap filled up, it's possible we'd see even better results at a larger size if we increased the size of the heap.

这篇关于引起GC一致性改变的技术的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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