Почему у меня есть несколько висящих потоков OkHttp ConnectionPool - PullRequest
0 голосов
/ 03 июня 2018

У меня есть приложение для Android, которое выполняет HTTP-запросы на получение в фоновом режиме.Я дам некоторые детали того, как это выполняется в ближайшее время.Сначала я остановлюсь на описании проблемы.

Я заметил в отладчике, что OkHttp ConnectionPool s складывается в окне Threads в Android Studio.Это касается меня, так как кажется, что это указывает на утечку ресурсов, и со временем они будут увеличиваться бесконечно (кажется).

Моя главная проблема заключается в том, что я понятия не имею, почему это происходит.Я почти уверен, что это моя вина, но я не знаю, что искать.Итак, мой общий вопрос:

«Что может вызвать создание нового пула при каждом выполнении HTTP-запроса?»

Во-первых, вот код, который я использую для выполнения запроса get.Обратите внимание, что это упрощено, но я бегу с этим точным кодом и вижу проблему.

private TestResult test() {
    final long startTime = SystemClock.elapsedRealtime();
    final String server = "connectivitycheck.gstatic.com";

    URL url;
    try {
        url = new URL("http", SOME_PATH);
    } catch (MalformedURLException e) {
        // We shouldn't get here since the url is well known
        return new TestResult(
                "failed to generate url " + e,
                SystemClock.elapsedRealtime() - startTime
        );
    }

    HttpURLConnection urlConnection = null;
    int httpResponseCode;
    try {
        urlConnection = (HttpURLConnection) url.openConnection();
        urlConnection.setInstanceFollowRedirects(false);
        urlConnection.setConnectTimeout(SOCKET_TIMEOUT_MS);
        urlConnection.setReadTimeout(SOCKET_TIMEOUT_MS);
        urlConnection.setUseCaches(false);
        InputStream is = urlConnection.getInputStream();
        httpResponseCode = urlConnection.getResponseCode();
        is.close();
    } catch (IOException e) {
        return new TestResult(
                e,
                SystemClock.elapsedRealtime() - startTime
        );
    } finally {
        if (urlConnection != null)
            urlConnection.disconnect();
    }
    if (httpResponseCode != HttpURLConnection.HTTP_NO_CONTENT) {
        return new TestResult(
                "invalid error code, expected 204 but got " + httpResponseCode,
                SystemClock.elapsedRealtime() - startTime
        );
    }

    return new TestResult(
            SystemClock.elapsedRealtime() - startTime
    );
}

Итак, когда этот код выполняется ...?

Во-первых, позвольте мне сказать, что я пытался запустить этот код из моей домашней активности в моем приложении (в отдельном потоке, поскольку HTTP не разрешен в основном потоке Android).Когда я это делаю, все в порядке.Я могу сделать несколько запросов и никогда не видеть более одного пула.

Ситуация, в которой я запускаю код и вижу проблемы, выглядит следующим образом:

  • У меня есть фон Service
  • В этой службе я запускаю новый Thread
  • В этой теме я создаю ExecutorService:

    ExecutorService executorService = Executors.newCachedThreadPool();
    CompletionService<FutureResult> completionService = new ExecutorCompletionService<>(executorService);
    
  • Используя это ExecutorService, я отправляю вызываемую задачу, которая запускает мой метод test (см. Выше).

Обратите внимание, что все это может показаться запутанным, но во всем этом есть смысл.Во-первых, ExecutorService будет выполнять много других задач, помимо запуска метода test.

Я хорошо выглядел для висящих ссылок, которые каким-то образом могли поддерживать живые базовые ресурсы HTTP, ноЯ ничего не вижу.

Кто-нибудь с хорошим знанием OkHttp знает, почему это может произойти?Я надеюсь, что некоторые идеи помогут мне раскрыть проблему.

1 Ответ

0 голосов
/ 04 июня 2018

Самый простой способ выяснить это - установить точку останова в конструкторе ConnectionPool и запустить ваше приложение.Это покажет, кто его создает.Я предполагаю, что это не связанный класс, такой как аварийный репортер или аналитическая библиотека.

...