我在找标杆的东西,而具有高量正在进行垃圾回收的竞争是如何执行。 我以前基准它的行为在一个稳定的,单线程运行,我现在想要做相同的测试更强调JVM; 基本上我想有后台线程创建,并在合理的步伐一致销毁对象。
我正在寻找关于如何实现一个稳定而GC密集型操作的建议。 它需要实现几个目标:
- 花费GC的时间像样的数目(比如20-50%)
- 做工作的基本一致量随着时间的推移,以及创建工作的一个类似的一致量为GC
- 免驱堆和触发
Java heap space
错误 - 避免过载GC和触发
GC overhead limit exceeded
错误
我实现了我自己的通的东西,可能会导致垃圾收集量稳定。 完整的代码可以在这里找到: https://bitbucket.org/snippets/dimo414/argzK
肉是这两种方法,其中构建体和释放出大量的对象为的实时(而不是线程的时间或CPU时间)给定时间段:
/**
* 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);
}
该类实现Runnable
,所以你可以启动它(或几个一次)在自己的后台线程。 它将为你只要指定运行,或者如果你喜欢,你可以启动它作为一个守护线程(所以它不会终止停止JVM),并指定与运行下去0
秒钟构造函数的参数。
我做了这个类的一些基准测试,发现它花了接近它的时候阻塞(想必对GC)和15-25%的用户流失标识近似最优值的第三和大小的〜500。 每次运行做了60秒,下方绘制图形线程时,如报道java.lang.managment.ThreadMXBean.getThreadCpuTime()
和该线程所分配的总字节数,如报道com.sun.management.ThreadMXBean.getThreadAllocatedBytes()
控制(0%流失率)不应该实质上引入任何GC,我们可以看到它分配几乎没有任何对象,并在线程花费近100%它的时间。 从5%至95%的流失率,我们看到相当一致大约三分之二的时间都花在线程,想必其他第三方花费在GC。 一个合理的比例,我会说。 有趣的是,在客户流失率的最高端,我们看到被消耗在线程更多的时间,大概是因为GC正在清理这么多,它实际上能够更有效率。 这似乎在20%左右是个不错的对象的数量被搅动每个周期。
该地块是如何在不同的目标大小的地图和列表线程功能,可以随着规模的增大有更多的时间必须在GC花看,有趣的,我们实际上最终分配较少的对象,因为大数据量意味着它无法使在同一时间内尽可能多的循环。 由于我们感兴趣的优化GC量翻腾JVM必须处理,我们希望它需要处理尽可能多的对象可能的,花尽可能少的时间尽可能在工作线程。 这似乎周围4-500是一个很好的目标大小,因此,因为它会产生大量的对象,并在花费GC良好的时间量。
所有这些测试用标准做java
设置,使之与堆玩可能会导致不同的行为-尤其〜2000年是我能填补堆之前设置的最大尺寸,它的可能,我们希望看到一个更好的结果较大的尺寸,如果我们增加了堆的大小。