javagarbage-collectionrocketmq

Why Thread.sleep(0) can prevent gc in rocketmq?


Recently I read source code in RocketMQ , but I can`t understand this code. Why this code can prevent gc?

https://github.com/apache/rocketmq/blob/master/store/src/main/java/org/apache/rocketmq/store/MappedFile.java

for (int i = 0, j = 0; i < this.fileSize; i += MappedFile.OS_PAGE_SIZE, j++) {
        byteBuffer.put(i, (byte) 0);
        // force flush when flush disk type is sync
        if (type == FlushDiskType.SYNC_FLUSH) {
            if ((i / OS_PAGE_SIZE) - (flush / OS_PAGE_SIZE) >= pages) {
                flush = i;
                mappedByteBuffer.force();
            }
        }

        // prevent gc
        if (j % 1000 == 0) {
            log.info("j={}, costTime={}", j, System.currentTimeMillis() - time);
            time = System.currentTimeMillis();
            try {
                Thread.sleep(0);
            } catch (InterruptedException e) {
                log.error("Interrupted", e);
            }
        }
 }

Solution

  • It does not.

    Thread's sleep documentation states only:

    Causes the currently executing thread to sleep (temporarily cease execution) for the specified number of milliseconds, subject to the precision and accuracy of system timers and schedulers. The thread does not lose ownership of any monitors.

    What it means it can have side effect on the behaviour of the garbage collector.

    By calling Thread.sleep(0), you are (potentially (it's a 0, so implementation could even ignore that)) switching context, and the parallel GC thread could be selected instead, to clean up other references. The minor side effect is that you potentially run GC more often - what can prevent long-running garbage collections (you are increasing a chance of GC run every 1000 iterations).