Создано слишком много потоков Smack Cache Executor

Версия Smack: 4.2.4

Когда большое количество сообщений (обычных сообщений и сообщений с задержкой повторной отправки) поступает в клиент Android, smack создает 100 ~ 200 спящих потоков Smack Cache Executor. Этот внезапный приток потоков приводит к тому, что клиент Android перестает отвечать (ошибка ANR).

При нормальных операциях будет как минимум 2 потока Smack Cache Executor, и приложение будет работать с 50-60 потоками.

Сообщения типа delay offline storage обрабатываются протоколом «Flexible Offline Message Retrieval». Однако для обычных сообщений и сообщений с задержкой, по-видимому, нет какого-либо специального протокола, и нет четких решений для увеличения количества потоков.

Большое количество сообщений здесь относится к 600+ повторно отправленным сообщениям и нормальным сообщениям, поступающим в течение нескольких секунд.

Любая помощь или совет по этому поводу приветствуются. Спасибо заранее!

Изменить 1:

3 Слушатели строфы настраиваются, когда соединение с XMPP аутентифицировано. Один для присутствия, один для сообщений и один для IQ. Вот они:

public void addPresenceStanzaListener(){
    if (presenceStanzaListener != null) {
        connection.removeSyncStanzaListener(presenceStanzaListener);
    }

    StanzaFilter presenceStanzaFilter = new StanzaTypeFilter(Presence.class);

    presenceStanzaListener = new StanzaListener() {
        @Override
        public void processStanza(Stanza packet) throws SmackException.NotConnectedException, InterruptedException {
        //Process presence stanza
        }
    };
    connection.addSyncStanzaListener(presenceStanzaListener, presenceStanzaFilter);
}

public void addMessageStanzaListener(){
    if (messageStanzaListener != null) {
        connection.removeSyncStanzaListener(messageStanzaListener);
    }

    StanzaFilter messageStanzaFilter = new StanzaTypeFilter(Message.class);
    messageStanzaListener = new StanzaListener() {
        @Override
        public void processStanza(Stanza packet) throws SmackException.NotConnectedException, InterruptedException {
        //Process message stanza
        }
    };

    connection.addSyncStanzaListener(messageStanzaListener, messageStanzaFilter);
}

public void addIQStanzaListener(){
    if (iqStanzaListener != null) {
        connection.removeSyncStanzaListener(iqStanzaListener);
    }

    StanzaFilter iqStanzaFilter = new StanzaTypeFilter(IQ.class);
    iqStanzaListener = new StanzaListener() {
        @Override
        public void processStanza(Stanza packet) throws SmackException.NotConnectedException, InterruptedException {
        //Process IQ stanza
        }  
    };

    connection.addSyncStanzaListener(iqStanzaListener, iqStanzaFilter);
}

Как запускается увеличение количества потоков Smack Cache Ex:

  1. Отключить интернет-соединение
  2. Спам 600+ сообщений
  3. Снова включите подключение к Интернету (на этом этапе, с точки зрения ejabberd, клиент Android никогда не отключался от него)
  4. В тот момент, когда клиент подключается к XMPP, количество потоков Smack Cache Ex увеличивается как минимум на 100.

person xun_haylee    schedule 06.12.2018    source источник


Ответы (1)


Вы, вероятно, используете асинхронный слушатель строфы, когда вам следует использовать синхронные.

В конечном итоге вы сможете отследить точного слушателя (при условии, что он на самом деле вызван StanzaListener, но даже это не проверено прямо сейчас), который создает все эти потоки. Если вы определили, и это настройка прослушивателя от Smack, вам, вероятно, следует сообщить об этом как о проблеме на форумах сообщества Smack. Если вы настроили слушатель, то вы, возможно, захотите использовать синхронный слушатель или AsyncButOrdered утилиту Smack, чтобы уменьшить количество потоков.

person Flow    schedule 06.12.2018
comment
Спасибо за ответ. В настоящее время используется SyncStanzaListener. Какие-нибудь другие возможности? Или любую другую информацию, которая вам нужна? - person xun_haylee; 06.12.2018
comment
Синхронные прослушиватели не используют службу исполнителя, поскольку они выполняются синхронно в цикле обработки соединений. - person Flow; 06.12.2018
comment
Я обновил исходный пост, добавив дальнейшие объяснения того, как он запускается, и фрагменты кода для инициализации слушателя строфы. Надеюсь, это даст вам лучшее понимание. - person xun_haylee; 06.12.2018