Tomcat и сборщик мусора подключений к базе данных - PullRequest
0 голосов
/ 29 ноября 2018

Я спросил (и ответил сам) этот вопрос пару дней назад и решил проблему, но я не совсем понимаю почему проблема была решена и надеялсячтобы получить некоторые пояснения.

По сути, я реализовал службу REST на основе jax-rs, которая извлекает информацию из базы данных RavenDB и возвращает это содержимое в потоке.У меня была проблема с закрытым итератором результатов работы с базой данных, из-за которого служба REST зависала (и не принимала дальнейшие запросы) после ровно 10 запросов.

Мой код примерно выглядит следующим образом:

public Response ...
    {
        (...)

        StreamingOutput adminAreaStream = new StreamingOutput()
        {
            ObjectWriter ow = new ObjectMapper().writer().withDefaultPrettyPrinter();

            @Override
            public void write(OutputStream output) throws IOException, WebApplicationException
            {
                try(IDocumentSession currentSession = ServiceListener.ravenDBStore.openSession())
                {
                    Writer writer = new BufferedWriter(new OutputStreamWriter(output));
                    (...)   
                    CloseableIterator<StreamResult<AdministrativeArea>> results;
                    (...)
                    writer.flush();
                    writer.close();
                    results.close();
                    currentSession.advanced().clear();
                    currentSession.close();
                }
                catch (Exception e)
                {
                    System.out.println("Exception: " + e.getMessage() + e.getStackTrace());
                }
            }
        };
        if(!requestIsValid)
            return Response.status(400).build();
        else
            return Response.ok(adminAreaStream).build();
    }

Из того, что я понимаю о жизненном цикле объекта в Java или, точнее, о достижимости объекта и сборке мусора, даже если я не закрыл этот CleasableIterator должным образом, он должен выйти из области видимости / стать недоступным к тому времени, когда мойМетод завершается со статусом 400 или 200 - и, следовательно, получает мусор.

Просто чтобы прояснить: я, конечно, не предлагаю, чтобы никто не закрывал правильно открытые соединения и т. Д. - я это делаю сейчас - или полагаюсь на механизм сборки мусора Java, чтобы спасти нас от ленивого / нечистого кодирования.Я просто пытаюсь понять, как именно эти незакрытые итераторы могли вызвать поведение Tomcat.

Фактически, я предполагаю, что нам даже не нужно знать подробности о реализации итератора, потому что на «галактическом уровне» Java жизненный цикл объекта, различия в реализации не имеют значения.=> «Как только объект стал недоступным, не имеет значения, как именно он был закодирован».Единственное, что я могу себе представить, это то, что Tomcat каким-то образом (через механизм контейнера?) Немного меняет здесь игру и заставляет вещи «зависать».Может ли кто-нибудь пролить свет на это?

Заранее спасибо!

1 Ответ

0 голосов
/ 29 ноября 2018

CloseableIterator относится к CloseableHttpResponse, которое относится к HTTP-соединению.Финализатор не освобождает ответ или соединение, когда CloseableIterator больше не доступен.Вы создали утечку соединения.Ваша ошибка похожа на описанную здесь: https://phillbarber.blogspot.com/2014/02/lessons-learned-from-connection-leak-in.html

Смотрите здесь, почему методы finalize для освобождения ресурсов - плохая идея: https://www.baeldung.com/java-finalize

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...