JavaでMemory Mapped FileまたはMappedByteBufferを使用する理由

4313 ワード

JDK 1.4以降、Javaメモリマッピングファイル(Memory Mapped Files)はjava.nioパッケージにすでに存在していますが、多くのプログラム開発者にとってかなり新しい概念です.NIO導入後、Java IOはかなり速く、メモリマッピングファイルはJavaが達成する可能性のある最も速いIO操作を提供しています.これは、高性能Javaアプリケーションがメモリマッピングファイルを使用してデータを永続化すべき理由でもあります.これはいくつかの取引が非常に頻繁な場合に多く応用されており、これらの場合、電子取引システムは非常に迅速で、一方向遅延はミリ秒レベル未満であることが要求されている.IOは高性能システムの主な注目点であり、メモリマッピングファイルはdirectまたはnon-directバイトキャッシュ(Byte buffer)を使用してメモリを直接読み書きすることができます.メモリマッピングファイルの重要な利点は、オペレーティングシステムが実際の読み書きを担当することです.プログラムがメモリに書き込まれたばかりで切れても、オペレーティングシステムはメモリ内のデータをファイルシステムに書き込むことができます.もう1つのより顕著な利点は、共有メモリであり、メモリマッピングファイルは複数のプロセスで同時にアクセスでき、低遅延共有メモリの役割を果たすことです.
 
Javaメモリマッピングファイル/IOとは
メモリマッピングファイルは、Javaプログラムがメモリから直接アクセスできる特殊なファイルです.ファイル全体またはファイルの一部をメモリにマッピングし、オペレーティングシステムがページリクエストとファイルの書き込みを担当することで、アプリケーションはメモリデータを処理するだけで、非常に迅速なIO操作を実現できます.メモリマッピングファイルに使用されるメモリはJavaのスタックスペース以外です.Javaのjava.nioパッケージはメモリマッピングファイルをサポートし、MappedByteBufferを使用してメモリを読み書きできます.
 
メモリマッピングファイルのメリットとデメリット
メモリマッピングIOの主な利点はパフォーマンスであり、メモリマッピングファイルは通常のIOを介してファイルにアクセスするよりも速く、忙しい電子取引システムにとって非常に重要である可能性があります.メモリマッピングIOのもう一つの利点は、通常の方法ではアクセスできない大きなファイルをロードできることであり、実験により、メモリマッピングIOは大きなファイル処理でよりよく表現されていることが明らかになった.しかし、欠点はページエラー(page fault)を増加させる可能性があることです.オペレーティングシステムはファイルの一部をメモリにロードするだけで、要求されたページがメモリにない場合、ページエラーが発生します.Windows、Unix、Solaris、その他のクラスUnixなどの主流のオペレーティングシステムの多くは、メモリマッピングIOをサポートしています.64ビットアーキテクチャでは、ほとんどのファイルをメモリにマッピングし、Javaアクセスを直接使用することができます.もう1つの利点は、これらのファイルを共有し、プロセス間で共有メモリを提供し、通常のloopbackインタフェースベースのSocketよりも10倍速いことです.
 
JavaでのMappedByteBuffer読み書きサンプル
次の例では、メモリマッピングファイルを使用して読み書きする方法を示します.RandomAccessFileを使用してファイルを開き、FileChannelのmap()メソッドを使用してメモリにマッピングします.map()メソッドにはmode,position,sizeの3つの入力パラメータがあります.戻り値MappedByteBufferは、メモリマッピングファイルを処理するためのバイトキャッシュです.
 
import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;


public class MemoryMappedFileInJava {


    private static int count = 10485760; // 10 MB


    public static void main(String[] args) throws Exception {


        RandomAccessFile memoryMappedFile = new RandomAccessFile("largeFile.txt", "rw");


        // Mapping a file into memory
        MappedByteBuffer out = memoryMappedFile.getChannel().map(FileChannel.MapMode.READ_WRITE, 0, count);


        // Writing into Memory Mapped File
        for (int i = 0; i < count; i++) {
            out.put((byte) 'A');
        }
        System.out.println("Writing to Memory Mapped File is completed");


        // reading from memory file in Java
        for (int i = 0; i < 10; i++) {
            System.out.print((char) out.get(i));
        }
        System.out.println("Reading from Memory Mapped File is completed");


        memoryMappedFile.close();
    }


}

 
まとめ
 
JavaメモリマッピングファイルとIOをすばやくまとめます
1).Java言語java.nioパッケージでメモリマッピングファイルとIOをサポートします.
2).メモリマッピングファイルは、多忙な電子取引システムなど、性能に対する要求が高いシステムで使用される.
3).メモリマッピングIOを使用すると、ファイルの一部をメモリにロードできます.
4).要求されたページがメモリにない場合、メモリマッピングファイルによってページエラーが発生する
5).1つのファイル区間をメモリにマッピングする能力は、メモリのアドレス可能範囲に依存する.32ビットマシンでは、4 GB、すなわち2^32ビットを超えることはできません.
6).Java内のメモリマッピングファイルはストリームIOよりも速い(注:大きなファイルでは正しいが、小さなファイルでは必ずしもそうではない)
7).ファイルをロードするメモリはJavaのスタックメモリの外にあり、共有メモリに存在し、2つの異なるプロセスがファイルにアクセスできるようにします.ちなみに、これはdirectバイトキャッシュとnon-directバイトキャッシュのどちらを使用するかに依存します.
8).メモリマッピングファイルの読み書きはオペレーティングシステムが担当するため、Javaプログラムがメモリに書き込まれた後に停止しても、オペレーティングシステムが正常に動作している限り、データはディスクに書き込まれます.
9).Directバイトキャッシュはnon-directバイトキャッシュより性能がよい
10).MappedByteBuffer.force()メソッドを頻繁に呼び出さないでください.このメソッドは、オペレーティングシステムにメモリ内のコンテンツをハードディスクに書き込むように強制します.したがって、メモリマッピングファイルを書くたびにforce()メソッドを呼び出すと、メモリマッピングファイルから実際に利益を得ることはできません.disk IOとはあまり差がありません.
11).電源障害またはホストがダウンした場合、メモリマッピングファイルがディスクに書き込まれていない可能性があり、重要なデータが失われる可能性があります.
12).MappedByteBufferとファイルマッピングは、GCにキャッシュされる前に有効です.sun.misc.Cleanerは、メモリマッピングファイルを消去する唯一の選択である可能性があります.
 
JavaメモリマッピングファイルとメモリマッピングIOについてお話しします.これはかなり役に立ちます.もっと詳しく理解してほしいです.忙しい電子取引システムと関係がある場合は、メモリマッピングファイルを使用する可能性があります.
テキストリンク:http://javarevisited.blogspot.hk/2012/01/memorymapped-file-and-io-in-java.html