这个简单的示例代码演示了这个问题。我创建了一个ArrayBlockingQueue
, 和一个线程,该线程使用take()
. 循环结束后,理论上队列和线程都可以被垃圾回收,但实际上我很快就会得到一个OutOfMemoryError
. 是什么阻止了这被 GC'd,以及如何解决这个问题?
/**
* 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,但这无济于事。