次のコードで Java ヒープの枯渇の問題が発生する理由を実験してPipedInputStream
いますが、理解できません。PipedOutputStream
作成されたすべての一時String
オブジェクトはgc -ed にする必要があります。なぜ私は得るのOutOfMemoryError
ですか?
String
100 万文字ごとに 1000 個のオブジェクトを読み書きしようとしています。以下のコードは、 で呼び出しても途中で失敗します-Xmx2g
。さらにトレースは何ですか:
written string #453
read string #453
written string #454
Exception in thread "Thread-0" java.lang.OutOfMemoryError: Java heap space
... が の「後ろ」にPipedInputStream
ある唯一のオブジェクトであることを明らかにします。ガベージ コレクションが必要なすべてのヒープ メモリを再利用できなかった理由がわかりません。String
PipedOutputStream
import java.io.*;
import java.util.*;
class Worker implements Runnable {
private ObjectOutputStream oos;
private PipedInputStream pis;
public Worker() throws IOException {
this.pis = new PipedInputStream();
this.oos = new ObjectOutputStream(new PipedOutputStream( pis ));
}
@Override
public void run() {
try {
for (int i = 0 ; i < 1000 ; i++) {
oos.writeObject(aBigString());
System.out.printf("written string #%d\n", i);
}
oos.flush();
oos.close();
} catch (IOException e) {
throw new RuntimeException(e.getMessage());
}
}
private static String aBigString() {
StringBuffer sb = new StringBuffer();
for (int i = 0 ; i < 1000*1000 ; i++)
sb.append("X");
return sb.toString();
}
public PipedInputStream getInput() {
return this.pis;
}
}
public class FooMain {
public static void main(String args[]) throws IOException, ClassNotFoundException {
Worker worker = new Worker();
(new Thread(worker)).start();
ObjectInputStream ois = new ObjectInputStream(worker.getInput());
String record = null;
int i = 0;
try {
while (true) {
record = (String) ois.readObject();
System.out.printf("read string #%d", i++);
}
} catch (EOFException e) {
ois.close();
System.out.println("done.");
}
}
}