2010-08-16 56 views
0

我有一个Android应用程序,我使用HashMap,其中我保持我的线程(值)每个执行任务(Runnable)。为了确定线程我使用字符串作为键。只要他们执行通常不太长的任务,线程就会一直存在。问题是它们在完成并从HashMap中删除后似乎从未被GC释放过(并且它们不在其他地方引用)。如果我创建了我的应用程序的转储,那么在应用程序的整个生命周期中,我的内存中的任务数量就与我一样多。试图使用HashSet来代替,但结果相同。内存泄漏与Android上的HashMap/HashSet

在代码中,我开始跟他们这几行:

Thread image_fetch_thread = new Thread(new ImageFetchTask(image_url, this)); 

this.running_image_fetch_threads.put(image_url, image_fetch_thread); 

image_fetch_thread.start(); 

,并在某一时刻后,他们成为去除:

this.running_image_fetch_threads.remove(image_url); 

为什么GC不喜欢收集的?

+0

我只是做了android系统中的几件事情,但你真的确定你应该保持地图的线程?在桌面Java中,我会说这是一个明确的代码恶意。 – bwawok 2010-08-17 19:00:23

回答

0

你有多确定你是其实将他们从HashMapHashSet中删除?创建转储时,该集合的size()是什么?

+0

我使用remove(key)来删除按键的线程,甚至确保每次调用size()时都调用GC。所以我认为这个删除至少有效。 – georgij 2010-08-17 11:07:46

1

你确定你的线程正在完成吗?即使你在HashMap中删除了对你的Thread的引用,如果它没有真正完成,它也不会被GCed。运行方法必须完成才能发生。

+0

是的,他们肯定会完成(他们很简单,没有循环)。它们在从集合中移除时还没有完成,因为删除是从线程本身触发的,作为完成之前的最后一个操作。这可能是一个问题吗? – georgij 2010-08-17 10:35:32

+0

不,只要将它们从地图中移除,一旦线程完成,它们应该有资格收集。你能发布一些示例代码吗? – Robin 2010-08-17 13:44:41