あなたの質問は「メインスレッドが実行されている正確な時間」を測定することだけです。これを知るには、ガベージコレクタのブロック時間を測定する必要はありません。
スレッドが実行された時間は、そのCPU時間に対応します。 I/Oを待っている時間も考慮する必要がある場合は、この方法はうまくいかないでしょうが、ガベージコレクタがスレッドを一時停止する時間は無視してください。
私はあなたのために一緒にコンセプトの簡単な証明を置く:
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadMXBean;
import java.util.concurrent.TimeUnit;
public class CpuTime
{
public static void main(String[] args) {
// We obtain the thread mx bean and check if it support CPU time measuring.
final ThreadMXBean threadMxBean = ManagementFactory.getThreadMXBean();
if (!threadMxBean.isThreadCpuTimeSupported())
throw new IllegalStateException("CPU time not supported on this platform");
// This is important because the default value is platform-dependent.
threadMxBean.setThreadCpuTimeEnabled(true);
// Now we start the measurement ...
final long threadId = Thread.currentThread().getId();
final long wallTimeStart = System.nanoTime();
final long cpuTimeStart = threadMxBean.getThreadCpuTime(Thread.currentThread().getId());
// ... and do stupid things to give the garbage collector some work.
for (int i = 0; i < 1_000_000_000; i++) {
Long l = new Long(i);
}
// Finally we measure the cpu and wall time.
final long wallTime = System.nanoTime() - wallTimeStart;
final long cpuTime = threadMxBean.getThreadCpuTime(threadId) - cpuTimeStart;
System.out.println("CPU time: " + TimeUnit.NANOSECONDS.toMillis(cpuTime));
System.out.println("Wall time: " + TimeUnit.NANOSECONDS.toMillis(wallTime));
}
}
は、このアプローチは絶対に正確な結果を得るためにいくつかの調整が必要であることに注意してください。しかし、それはあなたを始めなければなりません。 GCログおよびMBeanのほかに
質問を編集して、GC休止やメインスレッドの実行時間を測定するかどうかを明確にしてください。これらは2つの全く異なる指標であり、一方は他方の指標から派生していません。 – apangin
時間は1)メインスレッドがGCによって停止されなかった、または2)VMセーフポイントになかった、または3)実際にCPUで実行されていた - これらはすべて異なる時期です。 – apangin