5 ~ 6 個のスレッドを作成するアプリケーションを考えてみましょう。サイクル内の各スレッドは、5 MB のページ サイズに MappedByteBuffer を割り当てます。
MappedByteBuffer b = ch.map(FileChannel.MapMode.READ_ONLY, r, 1024*1024*5);
遅かれ早かれ、アプリケーションが大きなファイルを処理すると、oom がスローされます
java.io.IOException: Map failed at sun.nio.ch.FileChannelImpl.map(FileChannelImpl.java:758)
Caused by: java.lang.OutOfMemoryError: Map failed
at sun.nio.ch.FileChannelImpl.map0(Native Method)
at sun.nio.ch.FileChannelImpl.map(FileChannelImpl.java:755)
仕様によると、MappedBuffer は GC 自体であるとすぐにダイレクト メモリを破棄する必要があります。問題は、MappedBuffer の GC 処理が遅すぎて、後でダイレクト メモリが終了したことです。
この状況を回避するには?おそらくMappedBufferを暗黙的に破棄するか、MappedBufferのある種のプールを使用すると言います