なぜか"な貯蔵はこのコマンド"Javaを用いたMappedByteBuffers?
-
20-09-2019 - |
質問
私は非常に大きなdouble値の配列を私が使っているディスクに基づくファイル、ページングのリストMappedByteBuffers取扱いは、 この質問 詳します。私はWindows XPにはJavaを用いた1.5となった。
このキーの一部コードの配置のバッファに対するファイル...
try
{
// create a random access file and size it so it can hold all our data = the extent x the size of a double
f = new File(_base_filename);
_filename = f.getAbsolutePath();
_ioFile = new RandomAccessFile(f, "rw");
_ioFile.setLength(_extent * BLOCK_SIZE);
_ioChannel = _ioFile.getChannel();
// make enough MappedByteBuffers to handle the whole lot
_pagesize = bytes_extent;
long pages = 1;
long diff = 0;
while (_pagesize > MAX_PAGE_SIZE)
{
_pagesize /= PAGE_DIVISION;
pages *= PAGE_DIVISION;
// make sure we are at double boundaries. We cannot have a double spanning pages
diff = _pagesize % BLOCK_SIZE;
if (diff != 0) _pagesize -= diff;
}
// what is the difference between the total bytes associated with all the pages and the
// total overall bytes? There is a good chance we'll have a few left over because of the
// rounding down that happens when the page size is halved
diff = bytes_extent - (_pagesize * pages);
if (diff > 0)
{
// check whether adding on the remainder to the last page will tip it over the max size
// if not then we just need to allocate the remainder to the final page
if (_pagesize + diff > MAX_PAGE_SIZE)
{
// need one more page
pages++;
}
}
// make the byte buffers and put them on the list
int size = (int) _pagesize ; // safe cast because of the loop which drops maxsize below Integer.MAX_INT
int offset = 0;
for (int page = 0; page < pages; page++)
{
offset = (int) (page * _pagesize );
// the last page should be just big enough to accommodate any left over odd bytes
if ((bytes_extent - offset) < _pagesize )
{
size = (int) (bytes_extent - offset);
}
// map the buffer to the right place
MappedByteBuffer buf = _ioChannel.map(FileChannel.MapMode.READ_WRITE, offset, size);
// stick the buffer on the list
_bufs.add(buf);
}
Controller.g_Logger.info("Created memory map file :" + _filename);
Controller.g_Logger.info("Using " + _bufs.size() + " MappedByteBuffers");
_ioChannel.close();
_ioFile.close();
}
catch (Exception e)
{
Controller.g_Logger.error("Error opening memory map file: " + _base_filename);
Controller.g_Logger.error("Error creating memory map file: " + e.getMessage());
e.printStackTrace();
Clear();
if (_ioChannel != null) _ioChannel.close();
if (_ioFile != null) _ioFile.close();
if (f != null) f.delete();
throw e;
}
を取得します。エラーのタイトルした後の配分第二-第三バッファです。
と思ったという連続したメモリなどでいう異なるサイズと数字のページもいております。
ようにな "い収納が採用のこのコマンド" 意味かばいけているのでしょうか?
と思ったのMappedByteBuffersした能力を扱うことができる構造に大き、ヒープを大切にしていきます。
他のヒン?
編集:
応答え以下の(@adsk)私は、コードをいものです。シングルで活躍MappedByteBufferです。私はを参照して地域のファイルのファイルは、現在付いジャンクの既存の地図を作成します。まだまだ同じエラー後約3地図。
バグを修正価とのGCは収集のMappedByteBuffersいう問題は、JDK1.5.
解決
と思ったのMappedByteBuffersした能力を扱うことができる構造に大き、ヒープを大切にしていきます。
No.うにしたものを使用してアドレス以上2**31兼ね...を想定した十分なメモリ使用した64ビットJVM.
(私はここでフォローアップの問題 この質問.)
編集:明確に、より説明が必要です。
が限界として知られています。
Javaは、基本的な制限の
length
属性の配列は、配列の指数型int
.これに併せ、このint
署名され、配列でなければいけません負のサイズに可能な限り最大の配列で2**31
ます。この制限に適用され32bit版、64bit JVMs.この基本である、Java言語...のようなことchar
値から0
へ65535
.用32bit JVMの場所a(理論)上限の
2**32
のバイト数が抗のJVM.これには、ヒープコード、図書館の授業のご使用になることは、JVMのネイティブコードコア、メモリ使用のためにマップされたバッファー...ます。(実際には、によってのプラットフォームのOS 月 だかなり以下2**32
バイトアドレス空間です。)するパラメータ、javaコマンドラインの決定はどのヒープメモリのJVMでは 許可 申し込んで利用します。メモリマップを使用
MappedByteBuffer
オブジェなカウントへす。メモリの量のOSではLinux/UNIXの総額のスワップスペースの設定は、プロセスを制限です。同様の制限も適用します。もちろん、実行、64bit版のJVMの場合はホストOSは64bit対応、使用64bit対応ハードウェアをする場合には、Pentiumは、平行できます。)
最後に、量を物理メモリシステムが登場します。理論的には、の作成をご依頼くださいJVMの利用ヒープなどで多くの倍以上のマシンの物理メモリ。実際にはこの 悪いこと.場合は上に配置する仮想メモリ、システムの脱穀-アプリケーション性能はます。
のかは:
ご利用の場合、32ビットのJVM、ほとんどの場合に限らから
2**31
や2**32
バイトの連想メモリ。るのに十分なスペースを最大と2**29
や2**30
ダブルスどちらを使用するにしても配列またはマップされたバッファです。ご利用の場合は64ビットのJVMでは単一の配列
2**31
表示されます。理論上のマップされたバッファする2**63
バイト2**61
倍ものの、実質的な限界が約の量を物理メモリマシン。
他のヒント
メモリマッピングファイルでのアドレスは32ビットVM.この場合においてもファイルにマップされている、小さな塊とそのBytebufferはない。その理由はGCいキックに、バッファ.
のバグで http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6417205