2013-08-04 9 views
7

私は何度もストリームを使用していますが、実際にどのように動作するかについては決して読んでいません。ストリームは単なるメタファーであるということ以外、私はそれらについて多くを知りません。ストリームは一連のバイトを表します。私は彼らが実際にどのように動作するかについてよく分かりません。Javaでファイルストリームを開くと、ストリームに「ポインタ」を付ける機能を持つOSと対話しているようです。Javaのストリームはどのようにメモリ消費に影響しますか?

基本的に私の質問は、ストリームがメモリ消費にどのように影響するかです。例えば入力ストリームがあり、そこからの読み込みを開始すると、読み取られたバイト数でメモリ消費量が増加し始めますか? Javaでストリームを開くと、読み込みを開始する前に完全なファイルを実際にロードすることはありませんか? 1つのストリームから読み込み、別のストリームに直接書き込むと、読み込んだ(そしてバッファに潜在的に存在する)バイト数だけメモリが増えます。バイト配列をJavaで読み込むと、ファイルのサイズに合わせてメモリ消費量が増えますか?

奇妙な質問のように聞こえるかもしれませんが、私は理解のためにガイダンス/修正が必要な場合があります。ありがとう。

+0

ここでは非常に良い説明があります(http://www.ibm.com/developerworks/library/j-zerocopy/index.html)。また、バッファとメモリの使用方法についても説明します。 –

答えて

3

InputStreamから読み取った後に、メモリオーバーヘッドがほとんどありません。です。ファイルを開くためのOSのオーバーヘッドと、新しいオブジェクトの割り当てのためのJVMのオーバーヘッドはごくわずかです。また、デフォルトで8KBのBufferedInputStreamを使用する場合は、小さなオーバーヘッドが発生する可能性があります。

書き込みのオーバーヘッドは、どこに書き込むかによって異なります。 FileOutputStreamの場合は、上記と同じです。それがByteArrayOutputStreamの場合、最悪の場合、最良のケースでは(2 *ストリーム長)、では(3 *ストリーム長)バイトである。私。 InputStreamから10kバイトを30kバイトのバイト配列にコピーするのは、最悪の場合に割り当てられます。

これは、ByteArrayOutputStreamサイズが2倍に達したことに加え、toByteArray()を呼び出すときに新しいバッファを割り当てるためです。

5

上記の回答はすべて素晴らしい回答ですが、メモリ消費に関するオリジナルの質問には答えられないと思います。

Javaでは、複数の方法でストリームを見ることができます。最初に、最も低いレベルのストリームであり、最小限のメモリオーバヘッドで基礎となるOS(ファイル、ネットワークなど)と対話するRawストリームを持っています。次に、バッファストリームを使用して生ストリームをラップし、バッファリングを追加してパフォーマンスを大幅に向上させることができます。ストリームバッファリングはバッファリングに一定量のメモリオーバーヘッドを追加し、アプリケーションで設定できます。デフォルトが何であるかはわかりませんが、おそらく32Kなどの最小限のものでしょう。

第3の種類のストリームは、メモリストリーム(ByteArrayInput/Ouput)です。これらのストリームは、書き込み時にメモリとして使用され、必要に応じて拡張され、参照カウントが0になるまでメモリを破棄しませんもう使用されません)。これらのストリームは非常に便利ですが、明らかに多くのメモリを消費する可能性があります。

最後の型は実際にはストリームではなく、上で指摘したようにストリームとのデータ変換を支援するReadersと呼ばれるI/Oのクラスです。これらのストリームは、いずれかのrawで動作します。バッファされたストリームまたはメモリストリームであり、使用されている基本ストリームと同じ量のメモリを消費します。