Reputation: 635
I have this service:
@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);
}
I saw this example on the Android Bootcamp course on youtube and it worked. My question is: is that not a dangerous thing to do? because if the service will be stopped while the thread is sleeping its memory could be evicted by the GC and then the thread will try and access an unallocated variable(running)... I suspect it works because it adds + 1 to running's reference counter and that why it will only be evicted when the thread will be over but I would love for someone to confirm this and maybe give a detailed explanation of the process.
Thanks!.
Upvotes: 0
Views: 53
Reputation: 28706
if the service will be stopped while the thread is sleeping its memory could be evicted by the GC
This assumption is wrong.
May I suggest you this reading about Java GC. Here is a relevant quote:
Active Java threads are always considered live objects and are therefore GC roots.
So your thread is sleeping, but it is still in a running state. The fact that it is sleeping is not important here. What is important is that the thread is not finished yet (as you said in your question).
Thread is not finished, means that it is still active and so the thread is a GC-root.
Since it holds a reference to the member running
: the service won't be garbage collected.
Is it dangerous ? Yes ! because it is a potential memory leak, not because there is a risk to access to a unallocated variable.
To avoid memory leak you must ensure that at some point : your thread will finish (i.e. running
became false)... for every possible situation :
Upvotes: 1
Reputation: 9784
What you posted won't compile without declaring running
final. When you declare the variable final, the new instance of Thread
captures the value and the value will remain as is regardless of what happens on the outside.
There generally isn't such thing as accessing an unallocated variable in Java.
Upvotes: 0
Reputation: 2976
Since you have a running thread (it does not really sleep), it holds reference to the service. Which means service and everything service has access to will not be collected and released.
Upvotes: 0