我有这项服务:
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
running = true;
new Thread(){
@Override
public void run() {
super.run();
while (running) { Thread.sleep(60); ... }
}
}.start();
return super.onStartCommand(intent, flags, startId);
}
我在youtube上的Android Bootcamp课程中看到了这个例子,但它确实有效。 我的问题是:这不是一件危险的事吗?因为如果服务将在线程处于休眠状态时停止,其内存可能被GC逐出,然后线程将尝试访问未分配的变量(正在运行)...我怀疑它是有效的,因为它为运行的引用计数器增加了+ 1这就是为什么只有当线程结束时才会被驱逐,但我希望有人能够证实这一点,并且可能会详细解释这个过程。
谢谢!
答案 0 :(得分:1)
如果服务在线程处于休眠状态时停止,则其内存可能被GC逐出
这个假设是错误的。
我建议您{Java}提出this reading。这是一个相关的引用:
活动Java线程始终被视为活动对象,因此是GC根源。
所以你的线程正在休眠,但它仍处于运行状态。这是睡觉的事实并不重要。重要的是线程尚未完成(正如您在问题中所述)。
线程未完成,意味着它仍处于活动状态,因此该线程是GC根。
由于它拥有对成员running
的引用:服务不会被垃圾回收。
危险吗?是的!因为它是潜在的内存泄漏,不是因为存在访问未分配变量的风险。
为了避免内存泄漏,您必须确保在某些时候:您的线程将完成(即running
变为假)...对于每种可能的情况:
答案 1 :(得分:0)
由于您有一个正在运行的线程(它并没有真正睡眠),它会保留对该服务的引用。这意味着服务和所有服务都无法收集和发布。
答案 2 :(得分:0)
您发布的内容不会在未声明running
final的情况下编译。当您声明变量final时,Thread
的新实例会捕获该值,并且无论外部发生什么,该值都将保持不变。
通常没有在Java中访问未分配的变量。