2

ネットワーク経由でメッセージを取り込み、Java NIO MappedByteBuffer を使用して複数のメモリ マップ ファイルに書き込む Java 8 アプリケーションがあります。これらのファイルからメッセージを順番に同時に読み取り、MappedByteBuffer を使用して読み取りファイルを再度削除するリーダーがあります。約 246 GB のデータを読み書きし、アプリケーションが次のようにクラッシュするまで、すべてがスムーズです。

[thread 139611281577728 also had an error][thread 139611278419712 also had an error][thread 139611282630400 also had an error][thread 139611277367040 also had an error][thread 139611283683072 also had an error][thread 139611279472384 also had an error]





[thread 139611280525056 also had an error]
#
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGBUS (0x7) at pc=0x00007f02d10526de, pid=44460, tid=0x00007ef9c9088700
#
# JRE version: Java(TM) SE Runtime Environment (8.0_101-b13) (build 1.8.0_101-b13)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.101-b13 mixed mode linux-amd64 )
# Problematic frame:
# v  ~StubRoutines::jint_disjoint_arraycopy
#
# Core dump written. Default location: /home/user/core or core.44460
#
# An error report file with more information is saved as:
# /home/user/hs_err_pid44460.log

hs_err_pid44460.log空で、コア ダンプcore.44460のサイズは約 246 GB で、書き込もうとしているメッセージでいっぱいです。

最大ヒープ サイズ 32 GB で実行しています。JConsole によると、不足してFree Physical Memoryクラッシュします。 JConsole スクリーン キャプチャ

RAM が不足しているのはなぜですか? ファイル ハンドルを閉じるのを忘れているのですか / MMapped ファイルを正しく閉じていませんか?

4

3 に答える 3

1

あなたのプログラムは MappedByteBuffers の使用において実際に正しいかもしれませんが、割り当てのペースが速いと、前述のバッファーの割り当て解除がタイミングが悪いために現象が発生する可能性があることに注意してください。これは最終的には JVM の責任であり、バッファーのガベージ コレクション中にのみ発生するはずです。 . 要するに、バッファの解放は最終的に成功しますがそれがいつ起こるかはほとんど予測できません。

ただし、JVM のクリーナー機能 (クラス) を使用して、バッファーに割り当てられたメモリの割り当て解除 (「クリーニング」) を強制することはできますsun.misc.Cleanerいくつかの指示については、この SO の質問を参照してください。ただし、簡単に言えばCleaner.clean()、メモリ割り当ての数値を減らしてユース ケースを効果的にサポートするために、使い捨てバッファをできるだけ早く呼び出す必要があります。

于 2016-08-29T12:17:21.840 に答える