メモリバリアは、データキャッシュの一貫性を保証します。ただし、TLBの一貫性が保証されますか?
スレッド間でMappedByteBufferを渡すときに、JVM(java 7 update 1)がメモリエラー(SIGBUS、SIGSEG)でクラッシュすることがあるという問題が発生しています。
例えば
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とメモリバリアについての保証はありますか?
編集:OSはCentos 5.7ですが、i7およびDualXeonマシンでの動作を確認しました。
なぜ私はこれをするのですか?メッセージの書き込みにかかる平均時間は長さにもよりますが35〜100 nsであり、プレーンなwrite()の使用はそれほど高速ではないためです。現在のスレッドでメモリマップとクリーンアップを行う場合、これには50〜130マイクロ秒かかります。バックグラウンドスレッドを使用すると、メインスレッドがバッファを交換するのに約3〜5マイクロ秒かかります。なぜバッファを交換する必要があるのですか?私は多くのGBのデータを書き込んでおり、ByteBufferのサイズを2GB以上にすることはできないためです。