Как определить, какая часть трассировки стека вызывает утечку соединения в WebLogc 8.1

#connection #weblogic #memory-leaks #pool

#подключение #weblogic #утечки памяти #Бассейн

Вопрос:

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

         ####<May 21, 2011 1:16:06 PM EST> <Warning> <JDBC> <svrl003.sia.com> <svr3> <Finalizer> <<anonymous>> <> <BEA-001074> <A JDBC pool connection leak was detected. A connection leak occurs when a connection obtained from the pool was not closed explicitly by calling close() and then was disposed by the garbage collector and returned to the connection pool. The following stack trace at create shows where the leaked connection was created.  Stack trace at connection create:

        at weblogic.jdbc.wrapper.PoolConnection.init(PoolConnection.java:61)
        at weblogic.jdbc.pool.Driver.allocateConnection(Driver.java:254)
        at weblogic.jdbc.pool.Driver.connect(Driver.java:164)
        at weblogic.jdbc.jts.Driver.getNonTxConnection(Driver.java:540)
        at weblogic.jdbc.jts.Driver.connect(Driver.java:139)
        at weblogic.jdbc.common.internal.RmiDataSource.getConnection(RmiDataSource.java:329)
        at com.oco.util.BEndOcDBConnectionPool.getConnection(BEndOcDBConnectionPool.java:188)
        at com.oco.util.BEndOcDBConnectionPool.getConnection(BEndOcDBConnectionPool.java:144)
        at com.oco.util.BEndConnectionManager.getConnection(BEndConnectionManager.java:38)
        at com.oco.ejb.confirmation.OrderConfirmationBean.saveConsents(OrderConfirmationBean.java:10213)
        at com.oco.ejb.confirmation.OrderConfirmationBean.saveConsents(OrderConfirmationBean.java:10172)
        at com.oco.ejb.confirmation.OrderConfirmation_9rmehc_EOImpl.saveConsents(OrderConfirmation_9rmehc_EOImpl.java:2178)
        at com.oco.ejb.confirmation.OrderConfirmation_9rmehc_EOImpl_WLSkel.invoke(Unknown Source)
        at weblogic.rmi.internal.BasicServerRef.invoke(BasicServerRef.java:492)
        at weblogic.rmi.cluster.ReplicaAwareServerRef.invoke(ReplicaAwareServerRef.java:108)
        at weblogic.rmi.internal.BasicServerRef$1.run(BasicServerRef.java:435)
        at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:363)
        at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:147)
        at weblogic.rmi.internal.BasicServerRef.handleRequest(BasicServerRef.java:430)
        at weblogic.rmi.internal.BasicExecuteRequest.execute(BasicExecuteRequest.java:35)
        at weblogic.kernel.ExecuteThread.execute(ExecuteThread.java:224)
        at weblogic.kernel.ExecuteThread.run(ExecuteThread.java:183)
    > 
  

Похоже, это наводит на мысль, что я должен смотреть на com.oco.ejb.confirmation.Однако, могу ли я быть уверен, что это может быть com.oco.ejb.confirmation.bean.saveConsents.OrderConfirmationBean.saveConsents?

Спасибо!

Ответ №1:

Трассировка стека всегда показывает вам, что делал текущий поток в этот момент времени. Итак, построчный просмотр stacktrace — это довольно хороший способ расследования вашей конкретной проблемы.

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

 at weblogic.jdbc.common.internal.RmiDataSource.getConnection(RmiDataSource.java:329)
  

Это внутренний класс Weblogic, представляющий начало вызова для получения соединения из пула, в этот момент Weblogic понимает, что из-за утечки соединение недоступно

 at com.oco.util.BEndOcDBConnectionPool.getConnection(BEndOcDBConnectionPool.java:188)
at com.oco.util.BEndOcDBConnectionPool.getConnection(BEndOcDBConnectionPool.java:144)
at com.oco.util.BEndConnectionManager.getConnection(BEndConnectionManager.java:38)
  

Это 3 строки из кода вашего приложения, которое является ConnectionManager, который извлекает соединение. Я предполагаю, что это централизованно отвечает за управление всеми соединениями JDBC в вашем приложении — так что именно сюда вам следует обратиться, чтобы увидеть, что пошло не так.

 at com.oco.ejb.confirmation.OrderConfirmationBean.saveConsents(OrderConfirmationBean.java:10213)
  

Эта конкретная строка № 10213 метода OrderConfirmationBean saveConsents вызывает BEndConnectionManager — само по себе это может и не быть проблемой, то, что происходит, когда он выполняет вызов, вызывает проблему.

Итак, чтобы резюмировать, начните со строки № 10213 из OrderConfirmationBean saveConsents , и вы увидите, что вызов BEndConnectionManager может не закрывать соединения — теперь изучите свой код, чтобы увидеть, выполнено ли закрытие соединений или должно быть выполнено в OrderConfirmationBean или самим BEndConnectionManager .

Обновление, относящееся к BEA-001074

Я больше сосредоточился на трассировке стека, чем на BEA-001074.

Итак, BEA-001074 — это сообщение финализатора, выдаваемое при запуске сборщика мусора (GC). Итак, я понимаю, что происходит:

Соединение использовалось, но не было закрыто в коде, поэтому некоторая ссылка остается в куче JVM сервера Weblogic. Через некоторое время, когда запускается GC, он понимает, что соединение больше не активно, и запускает финализатор непосредственно перед сбором мусора. Затем BEA выдает ошибку, BEA-001074 чтобы сообщить нам, что потенциальная утечка была устранена путем удаления ссылки и возврата соединения в пул.

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

Weblogic способен воспроизвести трассировку стека, ссылающуюся на точку, в которой соединение (которое должно было быть закрыто) было фактически открыто.

Некоторые чтения на форумах Oracle показывают, что в некоторых версиях 8.1 они не способны воспроизвести трассировку стека, которая показывает Null exception passed — так что в вашем случае хорошо, что вы можете видеть фактический стек.

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

1. Привет, Йозек, просто где-то в строке WebLogic BEA-001074 я не понимаю. Похоже, что BEA-001074 указывает на утечку пула соединений, в то время как приведенная выше трассировка стека и ваше объяснение, похоже, предполагают, что произошла ошибка при попытке получить соединение из исчерпанного пула, поэтому возникает BEA-001074. Значит ли это, что WebLogic запрашивает BEA-001074 в ответ на исчерпанный пул? Извините, меня это смущает, поскольку я вижу это впервые.

2. @Chin: Я исправил свое объяснение — BEA 001074 представляет сообщение в более ПОЗДНИЙ момент времени, то есть во время GC, а не при попытке получить соединение из пула.

Ответ №2:

Убедитесь, что вы действительно отключили свои соединения. Убедитесь, что вы используете блок finally в блоке try / catch, чтобы освободить соединение для сценариев исключения catch.

Ответ №3:

Избегайте финализаторов, смотрите книгу Блоха «Эффективная Java». Нет гарантии, когда завершитель будет запущен, таким образом, вы можете удерживать соединения дольше, чем вы думаете, что приводит к утечке