记忆障碍和TLB

时间:2011-11-30 12:11:57

标签: java centos memory-mapped-files tlb memory-barriers

内存障碍可确保数据缓存一致。但是,它是否保证TLB一致?

我发现在线程之间传递MappedByteBuffer时,JVM(java 7更新1)有时会因内存错误(SIGBUS,SIGSEG)崩溃而出现问题。

e.g。

final AtomicReference<MappedByteBuffer> mbbQueue = new AtomicReference<>();

// in a background thread.
MappedByteBuffer map = raf.map(MapMode.READ_WRITE, offset, allocationSize);
Thread.yield();
while (!inQueue.compareAndSet(null, map));


// the main thread. (more than 10x faster than using map() in the same thread)
MappedByteBuffer mbb = inQueue.getAndSet(null);

没有Thread.yield()我偶尔会在force(),put()和C的memcpy()中崩溃,这些都表示我试图非法访问内存。使用Thread.yield()我没有遇到任何问题,但这听起来不是一个可靠的解决方案。

有没有人遇到过这个问题?有关TLB和内存障碍的保证吗?


编辑:操作系统是Centos 5.7,我已经看到了i7和双Xeon机器上的行为。

为什么我这样做?因为写入消息的平均时间是35-100 ns,具体取决于长度,使用普通的write()并不是那么快。如果我在当前线程中进行内存映射和清理,则需要50-130微秒,使用后台线程执行此操作需要大约3-5微秒的主线程交换缓冲区。为什么我需要交换缓冲区呢?因为我写了很多GB的数据而且ByteBuffer的大小不能超过2 GB。

1 个答案:

答案 0 :(得分:12)

映射是通过mmap64(FileChannel.map)完成的。访问地址时会出现页面错误,内核将为您读取/写入。在mmap期间不需要更新TLB。

TLB(所有cpus)在munmap期间未经验证,由mappedByteBuffer完成处理,因此munmap成本很高。

映射涉及大量同步,因此地址值不会被破坏。

你有机会通过Unsafe尝试花哨的东西吗?