Search code examples
javaparametersgarbage-collectionjmh

When should GC be set True in JMH experiments?


I read from StackOverflow post that setting GC true is not recommended because it removes GC heuristics. But I am wondering the scenarios when GC should be set to True.

For example, I have a Benchmark Method as below

@Benchmark
public int test(int a, int b){
   return a + b
}

If I want to measure specifically the execution of test(5,6). To avoid that JIT memorizes the results of the same inputs, I turned GC to True so that after each iteration the return value is erased by the forced GC.

Is this a valid scenario to set GC True?


Many thanks for pointing out the example could not run. Yes, I just made it up to start a conversion to talk about what are the valid scenarios to turn on GC. I am not going to use "@State" since I may also want to measure test(665,666). I am willing to take declare them as parameters and take their values from Java CLI.

Due to this made-up example, the conversion has been dragged away from the topic. So here it goes: What are the JMH experiments that GC should be turned on?


Solution

  • What you want to do does not work the way you think it does and neither has anything to do with GC. In your case, JIT optimizations and GC are un-related. I guess your best bet to understand what you get wrong and how is go through the samples of JMH. For an interesting one, see this, that explains how a wrong set-up of benchmark code can lead to wrong results, it somehow touches your point.

    If you want to measure what a + b takes, without the bias of JIT, then what you what to do is properly set-up JMH and not disable garbage collection, that will not help anyway.

    In general, you should take into account GC times in your tests, imo - because whatever the pause (if any), it is part of the benchmark per-se, due to your allocations. On the other hand, if you want to measure times without any GC implications, look at Epsilon GC, that does exactly that: it does nothing. And last point is that a and b must be passed by the JMH framework to your @Benchmark methods : read a bit more about @State.

    Even better if you would read the samples here (I would say at least the first 10 of them) and understand that you might test entirely unexpected things, like computation of a constant versus a real summation. Specifically, I think that you will benefit reading this example and and this one about constant folding.