将null设置为Thread以防止onDestroy Android中的内存泄漏

将null设置为Thread以防止onDestroy Android中的内存泄漏,android,multithreading,kotlin,garbage-collection,non-nullable,Android,Multithreading,Kotlin,Garbage Collection,Non Nullable,我正在使用线程进行一些异步操作。现在我主要有3个线程,如: private lateinit var horse1Thread: Thread private lateinit var horse2Thread: Thread private lateinit var timerThread: Thread 在活动的onDestroy()中调用stop()会导致UnsupportedOperationException,我考虑将这些值设置为null,以允许GC收集并防止内存泄漏。由于我的字段是

我正在使用线程进行一些异步操作。现在我主要有3个线程,如:

private lateinit var horse1Thread: Thread
private lateinit var horse2Thread: Thread
private lateinit var timerThread: Thread

在活动的
onDestroy()
中调用
stop()
会导致
UnsupportedOperationException
,我考虑将这些值设置为
null
,以允许GC收集并防止内存泄漏。由于我的字段是
非null
类型,我无法将它们设置为
null
。那么,这是我唯一的选择吗?还是kotlin提供了一种方法来释放这些字段所持有的内存?我可以将它们的类型设置为nullable,但我觉得这违背了目的

我认为您不应该关心将这些字段设置为null。线程应该完成他的工作,然后线程将处于终止状态。稍后垃圾收集器将在没有您的情况下清理它。您应该只关心这些线程的状态,并以这样的方式在这些线程中构建逻辑,以使它们能够在没有任何无休止循环的情况下完成工作


所以基本上,在线程内的长操作中需要一些触发器,通过单击按钮,这个触发器应该跳过(或取消)线程内的长操作。之后,线程将自己转到终止线程。

我认为您不应该关心将这些字段设置为null。线程应该完成他的工作,然后线程将处于终止状态。稍后垃圾收集器将在没有您的情况下清理它。您应该只关心这些线程的状态,并以这样的方式在这些线程中构建逻辑,以使它们能够在没有任何无休止循环的情况下完成工作


所以基本上,在线程内的长操作中需要一些触发器,通过单击按钮,这个触发器应该跳过(或取消)线程内的长操作。然后线程将自己转到终止的线程。

将它们设置为
null
没有任何作用,因为线程仍在运行,虚拟机将在运行时跟踪它们


您需要做的是引入一种方法来表示线程不应继续。这通常是通过检查循环中的
线程.isInterrupted()
并在为真时结束循环来完成的。然后,您只需要在
onDestroy
方法中调用
Thread.interrupt()
来清理线程。

将它们设置为
null
不会有任何作用,因为线程仍在运行,而虚拟机会在运行时跟踪它们


您需要做的是引入一种方法来表示线程不应继续。这通常是通过检查循环中的
线程.isInterrupted()
并在为真时结束循环来完成的。然后,您只需要在
onDestroy
方法中调用
Thread.interrupt()
来清理线程。

实际上,甚至还有一个关于
Thread.stop()
为什么不应该使用它的描述:

这种方法本质上是不安全的。使用thread.stop停止线程会导致它解锁所有已锁定的监视器(这是未经检查的ThreadDeath异常向堆栈上传播的自然结果)。如果以前受这些监视器保护的任何对象处于不一致的状态,则其他线程会看到损坏的对象,从而可能导致任意行为。stop的许多用法都应该被简单地修改某些变量以指示目标线程应该停止运行的代码所取代。目标线程应该定期检查该变量,如果该变量指示它将停止运行,则以有序的方式从其run方法返回


实际上,
Thread.stop()
中甚至有关于为什么不应该使用它的描述:

这种方法本质上是不安全的。使用thread.stop停止线程会导致它解锁所有已锁定的监视器(这是未经检查的ThreadDeath异常向堆栈上传播的自然结果)。如果以前受这些监视器保护的任何对象处于不一致的状态,则其他线程会看到损坏的对象,从而可能导致任意行为。stop的许多用法都应该被简单地修改某些变量以指示目标线程应该停止运行的代码所取代。目标线程应该定期检查该变量,如果该变量指示它将停止运行,则以有序的方式从其run方法返回


嗯。。我有疑问。当我没有保留任何对运行线程的引用时,GC不会在内存不足的情况下终止运行线程吗?我知道设置
null
不会终止它们,但相当于保留对它们的引用?@ArkaPravaBasu。如果安卓不一样的话,我会很惊讶的。。我有疑问。当我没有保留任何对运行线程的引用时,GC不会在内存不足的情况下终止运行线程吗?我知道设置
null
不会终止它们,但相当于保留对它们的引用?@ArkaPravaBasu。如果Android与众不同,我会感到惊讶。