3

I am creating many surface view instances to view some objects but one instance is created at a time and then surfaceDestroyed is called. but the thread I am creating every time on surfacecreated is being added to main ThreadGroup.

Although I am interrupting and nullifying it but it still resides in main ThreadGroup and creating low memory exception.

Code Snippets: constructor

public class MsurfaceView extends SurfaceView implements
        SurfaceHolder.Callback {
_thread = new mThread(this);
   _thread.setName("mThread");


@Override
    public void surfaceCreated(SurfaceHolder holder) {

        if (!_thread.isAlive()) {
            _thread = new BreedingThread(this);
        }

        _thread.setRunning(true);
        _thread.start();

    }





@Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        Log.d("mThread", "Surface Destroyed Called");
        getHolder().removeCallback(this);
        getHolder().addCallback(null);

        boolean retry = true;
        _thread.setRunning(false);

        while (retry) {
            try {
                _thread.interrupt();
                _thread.getThreadGroup().interrupt();
                _thread.join();
                retry = false;
            } catch (InterruptedException e) {
                Log.d("mThread", "Interrupted");
                // pass interrupt exception
                Thread.currentThread().interrupt(); 
                Log.d("mThread", "b4 threadGroupInterrupted");
                _thread.getThreadGroup().interrupt();
                _thread.getThreadGroup().list();//this shows thread is in //list
                _thread = null;
                break;
            }
        }
    }

UPDATE Thread.list function shows that my interrupted and null thread are still in threadgroup

06-10 15:22:52.780: INFO/System.out(1814): java.lang.ThreadGroup[name=main,maxPriority=10]
06-10 15:22:52.780: INFO/System.out(1814):     Thread[main,5,main]
06-10 15:22:52.780: INFO/System.out(1814):     Thread[Thread-2,5,main]
06-10 15:22:52.780: INFO/System.out(1814):     Thread[Binder Thread #1,5,main]
06-10 15:22:52.780: INFO/System.out(1814):     Thread[Binder Thread #2,5,main]
06-10 15:22:52.780: INFO/System.out(1814):     Thread[FlurryAgent,5,main]
06-10 15:22:52.780: INFO/System.out(1814):     Thread[AsyncTask #1,5,main]
06-10 15:22:52.780: INFO/System.out(1814):     Thread[AsyncTask #2,5,main]
06-10 15:22:52.780: INFO/System.out(1814):     Thread[Thread-17,5,main]
06-10 15:22:52.780: INFO/System.out(1814):     Thread[mThread,5,main]
06-10 15:22:52.780: INFO/System.out(1814):     Thread[mThread,5,main]
06-10 15:22:52.780: INFO/System.out(1814):     Thread[mThread,5,main]
06-10 15:22:52.780: INFO/System.out(1814):     Thread[Thread-38,5,main]
06-10 15:22:52.780: INFO/System.out(1814):     Thread[Timer-2,5,main]
06-10 15:22:52.780: INFO/System.out(1814):     Thread[mThread,5,main]
06-10 15:22:52.780: INFO/System.out(1814):     Thread[mThread,5,main]
06-10 15:22:52.780: INFO/System.out(1814):     Thread[Thread-53,5,main]
06-10 15:22:52.780: INFO/System.out(1814):     Thread[Thread-286,5,main]
06-10 15:22:52.780: INFO/System.out(1814):     Thread[Thread-327,5,main]
06-10 15:22:52.780: INFO/System.out(1814):     Thread[Thread-359,5,main]
06-10 15:22:52.780: INFO/System.out(1814):     Thread[mThread,5,main]
06-10 15:22:52.780: INFO/System.out(1814):     Thread[Thread-409,5,main]

how to remove them ?

AZ_
  • 21,688
  • 25
  • 143
  • 191
  • not complete code; just code snippets for understanding. I am creating this surfaceview and this thread after one is destroyed – AZ_ Jun 10 '11 at 10:07
  • As I said in your other thread. You don't need to remove them, and shouldn't remove them. You should instead correct your code so that your threads are terminated, and that you aren't referencing them. – Kaj Jun 10 '11 at 10:44
  • hProf analysis shows that only main ThreadGroup is referencing my BreedingThread – AZ_ Jun 10 '11 at 11:22
  • That means that the thread still is executing. – Kaj Jun 10 '11 at 11:28
  • System.out.println("isRunning "+_thread.isRunning()); ===> false System.out.println("isAlive "+_thread.isAlive());==>true – AZ_ Jun 10 '11 at 11:35
  • Thread is not running but thread is alive. how to kill this ? – AZ_ Jun 10 '11 at 11:36
  • @Aizaz. isRunning must be a flag that you have in your thread class, and you haven't posted the code for that class. We can't tell you what you have done wrong in code that we haven't seen. The thread is alive, and your flag has the wrong value. – Kaj Jun 10 '11 at 11:40

2 Answers2

1

Some things to look for.

  1. You are only calling _thread = null inside the catch block - this means it won't be set to null if the exception is never thrown. Move that inside a finally block.
  2. That exception is probably never thrown. Calling Thread.interrupt() will not throw it. That sets the thread's interrupt flag to true. That whole while loop is rather odd and you should probably re-write it.
  3. You are passing an instance of this to BreedingThread. Make sure that object is not holding a reference to your surface view forever
  4. Simply calling surface view destroy method does not mean the reference will be removed if something is still holding a reference to it (like I mention in 3 for example).
sksamuel
  • 16,154
  • 8
  • 60
  • 108
  • log prints out that thread is being interrupted. I used hprof with memory analyser and only shows that breedingThread is creating mess of memory overflow and all instances of surface view have been purged from memory. I am tanking _thread=null; into finally. thnx please help – AZ_ Jun 10 '11 at 10:39
0

When you call "new Thread" and do not specify a group, the thread will get added to the same group as the caller (i.e. Thread.currentThread().getThreadGroup()). In your case, that's what is causing your threads to be added to the "main" thread group. To change that behavior, use new Thread(group, this) to specify the group.

gMale
  • 17,147
  • 17
  • 91
  • 116