каждый раз, когда создается новый поток, добавляется в основную группу потоков

#android #multithreading #out-of-memory #threadgroup

#Android #многопоточность #не хватает памяти #threadgroup

Вопрос:

Я создаю множество экземпляров surface view для просмотра некоторых объектов, но за раз создается один экземпляр, а затем вызывается surfaceDestroyed. но поток, который я создаю каждый раз в surfacecreated, добавляется в основную группу потоков.

Хотя я прерываю и аннулирую его, но он по-прежнему находится в основной группе потоков и создает исключение нехватки памяти.

Фрагменты кода: конструктор

 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;
            }
        }
    }
  

Обновить
Нитки.функция list показывает, что мой прерванный и нулевой поток все еще находится в 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]
  

как их удалить ?

Комментарии:

1. не полный код; просто фрагменты кода для понимания. Я создаю этот surfaceview и этот поток после того, как один из них уничтожен

2. Как я уже говорил в вашем другом потоке. Вам не нужно их удалять, и не следует их удалять. Вместо этого вам следует исправить свой код, чтобы ваши потоки завершались и чтобы вы не ссылались на них.

3. Анализ hProf показывает, что только основная группа потоков ссылается на мой BreedingThread

4. Это означает, что поток все еще выполняется.

5. System.out.println(«isRunning » _thread.isRunning()); ===> false System.out.println(«IsAlive » _thread.IsAlive());==> true

Ответ №1:

На что следует обратить внимание.

  1. Вы вызываете _thread = null только внутри блока catch — это означает, что для него не будет установлено значение null, если исключение никогда не генерируется. Переместите это в блок finally.
  2. Это исключение, вероятно, никогда не выдается. Вызов Thread.interrupt() не приведет к его запуску. Это устанавливает флаг прерывания потока в значение true. Весь этот цикл while довольно странный, и вам, вероятно, следует его переписать.
  3. Вы передаете экземпляр этого в BreedingThread. Убедитесь, что объект не содержит ссылку на ваш surface view навсегда
  4. Простой вызов метода surface view destroy не означает, что ссылка будет удалена, если что-то все еще содержит ссылку на него (как я упоминал, например, в 3).

Комментарии:

1. в журнале выводится сообщение о том, что поток прерывается. Я использовал hprof с анализатором памяти и показывает только, что breedingThread создает беспорядок из-за переполнения памяти, и все экземпляры surface view были удалены из памяти. Я перевожу _thread=null; в finally. спасибо, пожалуйста, помогите

Ответ №2:

Когда вы вызываете «новый поток» и не указываете группу, поток будет добавлен в ту же группу, что и вызывающий (т.Е. Thread.currentThread().getThreadGroup() ). В вашем случае именно это приводит к добавлению ваших потоков в группу потоков «main». Чтобы изменить это поведение, используйте new Thread(group, this) для указания группы.