TomerZ
TomerZ

Reputation: 635

Android threads and services

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

Answers (3)

ben75
ben75

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 :

  • normal execution of the service (of course)
  • unexpected exception
  • service killed by the OS

Upvotes: 1

Steve M
Steve M

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

Volodymyr Lykhonis
Volodymyr Lykhonis

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

Related Questions