1

我遇到了 MappedByteBuffer 的问题,特别是它在内部的工作方式。我理解它的方式缓存完全由操作系统完成。因此,如果我从文件中读取(使用 MappedByteBuffer),操作系统将从硬盘驱动器读取整个页面并将页面保存在 RAM 中,以便在再次需要时更快地访问。这也允许为访问同一文件的多个应用程序/进程提供共享缓存。这个对吗?

如果是这样,如何使此缓存无效?只是重新初始化映射对象不应该工作。我编写了一个从硬盘驱动器读取大量数据的应用程序。我需要做一些基准测试,所以我需要在需要时清除这个缓存。我尝试使用“echo 3 > /proc/sys/vm/drop_caches”,但这并没有什么不同,所以我认为它不起作用。

4

2 回答 2

1

这也允许为访问同一文件的多个应用程序/进程提供共享缓存。这个对吗?

这就是它在 Linux、Windows 和 MacOS 上的工作方式。在其他操作系统上,它可能是相同的。

如果是这样,如何使此缓存无效?

删除该文件,它将不再有效。

我需要做一些基准测试,所以我需要在需要时清除这个缓存。

这就是操作系统的用途。如果您需要强制缓存无效,这很棘手并且完全依赖于操作系统。

我尝试使用“echo 3 > /proc/sys/vm/drop_caches”,但这并没有什么不同,所以我认为它不起作用。

它可能对您的基准测试没有影响。/proc/meminfo我建议你看看

Cached:           588104 kB
SwapCached:          264 kB

顺便说一句,如果您想取消映射 MappedByteBuffer 我执行以下操作

public static void clean(ByteBuffer bb) {
    if (bb instanceof DirectBuffer) {
        Cleaner cl = ((DirectBuffer) bb).cleaner();
        if (cl != null)
            cl.clean();
    }
}

这也适用于直接 ByteBuffers,但可能不适用于 Java 9,因为该接口将被删除。

于 2014-04-19T11:19:37.707 回答
0

这是已知的可悲问题(JDK 中仍未解决):http ://bugs.java.com/view_bug.do?bug_id=4724038

但即使没有公共 API,也有一个危险的解决方法(使用风险自负):https ://community.oracle.com/message/9387222

另一种方法是不使用巨大的 MappedByteBuffers 并希望它们最终会被垃圾收集。

如果想要映射此文件的不同程序需要使用他们自己的 MappedByteBuffer 副本从该文件中复制出来,MapMode.PRIVATE可能会有所帮助。

希望有帮助。

于 2014-04-19T11:16:54.300 回答