5

OutOfMemory例外を生成する次のコードがあります。

byte[] buf = new byte[10240];
int len = 0;
DataOutputStream dataOS = new DataOutputStream(conn.getOutputStream());
while ((len = _inputStream.read(buf)) > 0) {
    System.out.println("len : " + len);
    System.out.println("Going to write buf into dataOS : " + buf.length);
    dataOS.write(buf, 0, len);
    System.out.println("dataOS.size() : " + dataOS.size());
}
_inputStream.close();

以下は、デバッグ出力の最後の数行です。

len : 10240
Going to write buf into dataOS : 10240
dataOS.size() : 342804702
len : 10240
Going to write buf into dataOS : 10240
dataOS.size() : 342814942
len : 10240
Going to write buf into dataOS : 10240

342814942を超えてdataOSに書き込もうとすると、例外が発生します。

誰かが私がこれを処理するのを手伝ってくれませんか?

ありがとう!

4

2 に答える 2

14

これは、DataOutputStream(データをまったく保持しない)および基礎となるストリームとは何の関係もありませんconn.getOutputStream()。ここでは、関連するコードを表示していませんが、「conn」はHttpURLConnectionのインスタンスであると推測します。HttpURLConnectionの出力ストリームは、出力の長さを決定できるように出力をバッファリングすると思います(明示的に設定しない限り)。出力の長さがわかっている場合は、を使用して直接設定するHttpURLConnection.setFixedLengthStreamingModeか、を呼び出しHttpURLConnection.setChunkedStreamModeて、データを完全にメモリにバッファリングするのではなく、チャンクで送信できるようにすることができます。

将来、OOMEに遭遇したときは、常にヒープダンプを生成し、それをメモリプロファイラーで開く必要があります。これにより、ほとんどの場合、問題がどこにあるかがすぐにわかります(たとえば、DataOutputStreamではなく基になるストリーム内)。

于 2012-04-24T01:32:50.240 に答える
1

OutputStreamの実装によっては、書き込みによってコンテンツがメモリにバッファリングされ、実際には送信されない場合があります。十分なコンテンツをバッファリングすると、もちろんメモリが不足します。

ある間隔で、おそらくループを通過するたびに、を呼び出す必要がありますOutputStream.flush()。使用中のバッファがある場合、それはそれをクリアします。

于 2012-04-24T01:30:25.330 に答える