この簡単なサンプル コードは、問題を示しています。を作成しArrayBlockingQueue
、 を使用してこのキューでデータを待機するスレッドを作成しますtake()
。ループが終了した後、理論的にはキューとスレッドの両方をガベージ コレクションできますが、実際にはすぐにOutOfMemoryError
. これがGCされるのを妨げているのは何ですか?どうすれば修正できますか?
/**
* Produces out of memory exception because the thread cannot be garbage
* collected.
*/
@Test
public void checkLeak() {
int count = 0;
while (true) {
// just a simple demo, not useful code.
final ArrayBlockingQueue<Integer> abq = new ArrayBlockingQueue<Integer>(2);
final Thread t = new Thread(new Runnable() {
@Override
public void run() {
try {
abq.take();
} catch (final InterruptedException e) {
e.printStackTrace();
}
}
});
t.start();
// perform a GC once in a while
if (++count % 1000 == 0) {
System.out.println("gc");
// this should remove all the previously created queues and threads
// but it does not
System.gc();
}
}
}
Java 1.6.0 を使用しています。
更新: 数回繰り返した後に GC を実行しますが、これは役に立ちません。