2012-03-29 60 views
1

这是关于线程对象的android应用程序内存泄漏。Android内存泄漏新线程()

我不知道下面的代码导致内存泄漏,因为我开始了3年的android程序。

Thread t = new Thread(); 

t不被垃圾收集器检测到。

问题是我如何从vm内存释放局部变量t?

我决定尝试

我做了我的应用程序,它的行为是下面的代码按钮。

for(int i=0;i<1000;i++) 
{ 
    Thread t = new Thread(); 
} 

我预计局部变量t将在某天被释放。

我用调试模式执行它并打开E-clipse DDMS透视图。

我选择我的Android设备(2.3.6)在我的应用程序的线程,并点击“更新堆”按钮

所以我可以检查堆大小和实时分配。

它始于总堆大小5.445MB并分配2.779 MB。

然后我点击生成1000个线程对象的按钮。

它改变了堆大小5.508MB和分配3.058 MB。

正如您所知,DDMS透视图中存在“原因GC”按钮。

我点了那个按钮。但分配的内存仍然是3.058MB。

我再次点击我的按钮来产生另外1000个线程对象。

我点击无望的“Gause GC”按钮。

最终堆大小消失了大约20MB,并导致内存不足异常。

我该如何释放Thread实例对象?

+0

在大多数情况下,最好使用Executor而不是线程。如果你使用类似cachedThreadPool的东西,它会为你处理活动的线程。 http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/Executor.html – Jave 2012-03-29 08:22:12

回答

1

您正在使用的线程中完成后,调用interupt()

而且我不知道是否有必要,但按照Johannes的建议设置t=null可能是个好主意。

但是,在停止线程之后,由JVM的垃圾收集器处理线程本身的销毁。

+1

它不起作用.... for(int i = 0; I <1000;我++) \t \t \t \t { \t \t \t \t \t线程t =新主题(); \t \t \t \t \t t.start(); \t \t \t \t \t t.interrupt(); \t \t \t \t \t t = null; \t \t \t \t} – muyoungko 2012-03-29 13:09:44

+0

好吧。这真的没关系。应该没有实例需要创建1000个线程。而创建一个线程不会占用那么多的内存。 而你创建这么多线程的事实可能是问题的原因。如果您要创建一个,请插入它并将其设置为空,那么机会将从内存中清除。如果没有,那么我不相信你会做任何事情。 – Jakar 2012-03-30 07:29:40

+0

这实际上解决了这个问题,我使用12个Thread对象的数组在大约20分钟内创建了7000个线程。 @muyoungko我注意到你的for循环测试实际上没有运行或任何东西 - 也许这是问题的一部分...在启动()后过早调用interrupt()?在我的情况下,我有一个AtomicBoolean(用于多个线程的数组),它告诉我线程已完成 - 然后我在原始Thread对象上中断(),然后在同一个数组插槽中创建一个新线程。使用此解决方案,内存泄漏消失。 – 2015-03-05 18:02:25

0

我没有安卓设备来测试它,但我会认为一个线程需要在它不能被任何变量引用之前被垃圾收集之前去死。

开始尝试在你的循环线程这样的:

for(int i=0;i<1000;i++) 
{ 
    Thread t = new Thread(); 
    t.start(); 
    t = null; 
} 
+1

它不起作用 – muyoungko 2012-03-29 09:45:48