4

最近在看 RocketMQ 的源码,但是看不懂这段代码。为什么这段代码可以阻止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);
            }
        }
 }
4

1 回答 1

4

它不是。

线程的睡眠文档仅说明:

使当前执行的线程休眠(暂时停止执行)指定的毫秒数,取决于系统计时器和调度程序的精度和准确性。该线程不会失去任何监视器的所有权。

这意味着它会对垃圾收集器的行为产生副作用。

通过调用Thread.sleep(0),您(可能(它是 0,因此实现甚至可以忽略它))切换上下文,并且可以选择并行 GC 线程来清理其他引用。次要的副作用是您可能会更频繁地运行 GC - 这可以防止长时间运行的垃圾收集(您增加了每 1000 次迭代运行 GC 的机会)。

于 2018-11-13T15:37:59.243 回答