7

同じファイルを同時に読み取るスレッドがたくさんあり(全体で約1億)、ファイルを更新するスレッドは1つだけです。ファイルI/Oを減らすために、ファイルをメモリにマップしたいと思います。これはJavaでどのように行うことができますか?

私は基本的に次の2つの方法を検討しました。

  1. ファイルを格納するためのバイト配列を使用し、マルチスレッド読み取り時にバッファを読み取るために毎回ByteArrayInputStreamを作成します。
  2. NIOを使用して1つのファイルチャネルを取得し、チャネルを同期してMappedByteBufferから読み取り、マルチスレッド読み取りを行います。

メソッドが機能するかどうかはわかりません。より良い解決策がある場合は、いくつかのヒントを与えるのを手伝ってください。

4

1 に答える 1

12

各スレッドでNIOを使用して、独自のマッピングを作成し、独自のプライベートバッファー内のデータを読み取ります。プライベートバッファサイズを最適に保ちます。OSはファイルキャッシュ内のファイルをページ単位で読み取り、ページはプライベートバッファに読み込まれます。同じ領域が複数のスレッドによって読み取られる場合、データはファイルキャッシュ内の同じページから読み取られ、ファイルのI/Oサイクルが節約されます。以下は、これを示す小さな図です。それがよりよく理解するのに役立つことを願っています。

メモリマップトファイルio

上の図を参考にして、以下に説明を示します。ファイルの領域がメモリにマップされます。マッピングの作成は、ファイルの特定の部分から読み取りたいことを示す論理的なマーキングにすぎません。マッピングが作成されると、マップされた領域を読み取る準備が整います。読み取りを開始すると、OSはファイルデータをファイルキャッシュ内のページにフェッチします。リージョンは1つ以上のページにマップできます。ここで、ページを独自のプライベートバッファーに読み込みます(最適化するために一度に複数のページ)。他のスレッドが最初のスレッドと同じ領域を読み取っている可能性があるため、同じページをプライベートバッファに読み取ります。今回は、ページフォールトなしでファイルキャッシュから読み取りが行われることに注意してください。プライベートバッファを処理した後、さらに読むように要求します。マッピングの一部を一度にプライベートバッファに読み込んでいることに注意してください。ファイルは100MBで、10MBの部分をメモリにマップすることができます。そして、40KBのプライベートバッファがあり、最初に10MBのうち40KBを読み取ります。次に、次の40KBなどを要求します。OSは、読み取りたいデータがすでにキャッシュにフェッチされているかどうかを確認します。そうでない場合、ページフォールトが発生し、OSは要求されたデータをページにフェッチします。この場合も、複数のスレッドが同じ領域の読み取りを要求した場合、このデータを共有できます。独自のプライベートバッファを作成する代わりに、ファイルキャッシュ自体を読み取りに使用できます。ただし、ファイルが複数のリージョンで複数回同時に読み取られると、複数のページフォールトが発生する可能性があります。したがって、この場合は、最適なサイズのプライベートバッファを使用することをお勧めします。ファイルは100MBで、10MBの部分をメモリにマップすることができます。そして、40KBのプライベートバッファがあり、最初に10MBのうち40KBを読み取ります。次に、次の40KBなどを要求します。OSは、読み取りたいデータがすでにキャッシュにフェッチされているかどうかを確認します。そうでない場合、ページフォールトが発生し、OSは要求されたデータをページにフェッチします。この場合も、複数のスレッドが同じ領域の読み取りを要求した場合、このデータを共有できます。独自のプライベートバッファを作成する代わりに、ファイルキャッシュ自体を読み取りに使用できます。ただし、ファイルが複数のリージョンで複数回同時に読み取られると、複数のページフォールトが発生する可能性があります。したがって、この場合は、最適なサイズのプライベートバッファを使用することをお勧めします。ファイルは100MBで、10MBの部分をメモリにマップすることができます。そして、40KBのプライベートバッファがあり、最初に10MBのうち40KBを読み取ります。次に、次の40KBなどを要求します。OSは、読み取りたいデータがすでにキャッシュにフェッチされているかどうかを確認します。そうでない場合、ページフォールトが発生し、OSは要求されたデータをページにフェッチします。この場合も、複数のスレッドが同じ領域の読み取りを要求した場合、このデータを共有できます。独自のプライベートバッファを作成する代わりに、ファイルキャッシュ自体を読み取りに使用できます。ただし、ファイルが複数のリージョンで複数回同時に読み取られると、複数のページフォールトが発生する可能性があります。したがって、この場合は、最適なサイズのプライベートバッファを使用することをお勧めします。OSは、読み取りたいデータがすでにキャッシュにフェッチされているかどうかを確認します。そうでない場合、ページフォールトが発生し、OSは要求されたデータをページにフェッチします。この場合も、複数のスレッドが同じ領域の読み取りを要求した場合、このデータを共有できます。独自のプライベートバッファを作成する代わりに、ファイルキャッシュ自体を読み取りに使用できます。ただし、ファイルが複数のリージョンで複数回同時に読み取られると、複数のページフォールトが発生する可能性があります。したがって、この場合は、最適なサイズのプライベートバッファを使用することをお勧めします。OSは、読み取りたいデータがすでにキャッシュにフェッチされているかどうかを確認します。そうでない場合、ページフォールトが発生し、OSは要求されたデータをページにフェッチします。この場合も、複数のスレッドが同じ領域の読み取りを要求した場合、このデータを共有できます。独自のプライベートバッファを作成する代わりに、ファイルキャッシュ自体を読み取りに使用できます。ただし、ファイルが複数のリージョンで複数回同時に読み取られると、複数のページフォールトが発生する可能性があります。したがって、この場合は、最適なサイズのプライベートバッファを使用することをお勧めします。これにより、ファイルが複数のリージョンで複数回同時に読み取られた場合に、複数のページフォールトが発生する可能性があります。したがって、この場合は、最適なサイズのプライベートバッファを使用することをお勧めします。これにより、ファイルが複数のリージョンで複数回同時に読み取られた場合に、複数のページフォールトが発生する可能性があります。したがって、この場合は、最適なサイズのプライベートバッファを使用することをお勧めします。

于 2012-05-14T09:42:18.987 に答える