You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@karaf.apache.org by "Grzegorz Grzybek (JIRA)" <ji...@apache.org> on 2016/08/31 16:17:20 UTC

[jira] [Comment Edited] (KARAF-4687) ClassLoader leak with java.lang.Exception and karaf.exception library

    [ https://issues.apache.org/jira/browse/KARAF-4687?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15452658#comment-15452658 ] 

Grzegorz Grzybek edited comment on KARAF-4687 at 8/31/16 4:16 PM:
------------------------------------------------------------------

All leaks are related to {{java.lang.Exception#classContext}} field added for pax-logging in {{karaf/exception/src/main/java/java/lang/Exception.java}}. But actually also to {{backtrace}} field which is accessed only by native code (and actually hidden for reflection).

The problem is related to one of the worst patterns that are very very bad in OSGi - static instances of Throwables.
Even without the improvement for pax-logging (additional classContext field) there's natively visible field called {{backtrace}} - see more details here: https://github.com/eclipse/jetty.project/issues/868.

First leak can be solved by changing Class array into WeakReference<Class> array

Second leak can be fixed by using special JDK7 Throwable constructor that allows to configure whether stacktrace/backtrace should be set/initialized at all - this is great improvement for those who like static instances of Throwables. But *they should be avoided at all cost* in OSGi (and generally).

If only we could change xerces code to use this new constructor for org.apache.xerces.impl.XMLEntityScanner.END_OF_DOCUMENT_ENTITY static Throwable... If we could, we won't have to change Class array into WeakReference<Class> array...


was (Author: gzres):
All leaks are related to {{java.lang.Exception#classContext}} field added for pax-logging in {{karaf/exception/src/main/java/java/lang/Exception.java}}.

The problem is related to one of the worst patterns that are very very bad in OSGi - static instances of Throwables.
Even without the improvement for pax-logging (additional classContext field) there's natively visible field called {{backtrace}} - see more details here: https://github.com/eclipse/jetty.project/issues/868.

First leak can be solved by changing Class array into WeakReference<Class> array

Second leak can be fixed by using special JDK7 Throwable constructor that allows to configure whether stacktrace/backtrace should be set/initialized at all - this is great improvement for those who like static instances of Throwables. But *they should be avoided at all cost* in OSGi (and generally).

If only we could change xerces code to use this new constructor for org.apache.xerces.impl.XMLEntityScanner.END_OF_DOCUMENT_ENTITY static Throwable... If we could, we won't have to change Class array into WeakReference<Class> array...

> ClassLoader leak with java.lang.Exception and karaf.exception library
> ---------------------------------------------------------------------
>
>                 Key: KARAF-4687
>                 URL: https://issues.apache.org/jira/browse/KARAF-4687
>             Project: Karaf
>          Issue Type: Bug
>    Affects Versions: 2.4.4, 4.0.6, 3.0.8
>            Reporter: Grzegorz Grzybek
>
> Here's much worse leak I found in JVisualVM:
> {noformat}
> this     - value: org.apache.felix.framework.BundleWiringImpl #1
>  <- m_wiring     - class: org.apache.felix.framework.BundleWiringImpl$BundleClassLoaderJava5, value: org.apache.felix.framework.BundleWiringImpl #1
>   <- <classLoader>     - class: org.ops4j.pax.logging.slf4j.Slf4jLogger, value: org.apache.felix.framework.BundleWiringImpl$BundleClassLoaderJava5 #1
>    <- <class>     - class: org.ops4j.pax.logging.slf4j.Slf4jLogger, value: org.ops4j.pax.logging.slf4j.Slf4jLogger class Slf4jLogger
>     <- LOGGER     - class: org.apache.karaf.features.internal.FeaturesServiceImpl, value: org.ops4j.pax.logging.slf4j.Slf4jLogger #3
>      <- [19]     - class: java.lang.Class[], value: org.apache.karaf.features.internal.FeaturesServiceImpl class FeaturesServiceImpl
>       <- classContext     - class: org.apache.xerces.impl.XMLEntityScanner$1, value: java.lang.Class[] #23
>        <- END_OF_DOCUMENT_ENTITY (sticky class)     - class: org.apache.xerces.impl.XMLEntityScanner, value: org.apache.xerces.impl.XMLEntityScanner$1 #1
> {noformat}
> and
> {noformat}
> this     - value: org.apache.felix.framework.BundleWiringImpl #18
>  <- m_wiring     - class: org.apache.felix.framework.BundleWiringImpl$BundleClassLoaderJava5, value: org.apache.felix.framework.BundleWiringImpl #18
>   <- <classLoader>     - class: io.fabric8.api.scr.ValidatingReference, value: org.apache.felix.framework.BundleWiringImpl$BundleClassLoaderJava5 #16
>    <- <class>     - class: io.fabric8.api.scr.ValidatingReference, value: io.fabric8.api.scr.ValidatingReference class ValidatingReference
>     <- curator     - class: io.fabric8.zookeeper.curator.CuratorFrameworkLocator, value: io.fabric8.api.scr.ValidatingReference #1
>      <- [140]     - class: java.lang.Object[], value: io.fabric8.zookeeper.curator.CuratorFrameworkLocator class CuratorFrameworkLocator
>       <- elementData     - class: java.util.Vector, value: java.lang.Object[] #3790
>        <- classes     - class: org.apache.felix.framework.BundleWiringImpl$BundleClassLoaderJava5, value: java.util.Vector #120
>         <- <classLoader>     - class: io.fabric8.zookeeper.curator.ManagedCuratorFramework$State, value: org.apache.felix.framework.BundleWiringImpl$BundleClassLoaderJava5 #15
>          <- [93]     - class: java.lang.Class[], value: io.fabric8.zookeeper.curator.ManagedCuratorFramework$State class ManagedCuratorFramework$State
>           <- classContext     - class: org.eclipse.jgit.errors.StopWalkException, value: java.lang.Class[] #946
>            <- INSTANCE     - class: org.eclipse.jgit.errors.StopWalkException, value: org.eclipse.jgit.errors.StopWalkException #1
>             <- [332]     - class: java.lang.Object[], value: org.eclipse.jgit.errors.StopWalkException class StopWalkException
>              <- elementData     - class: java.util.Vector, value: java.lang.Object[] #3772
>               <- classes     - class: org.apache.felix.framework.BundleWiringImpl$BundleClassLoaderJava5, value: java.util.Vector #119
>                <- <classLoader>     - class: org.eclipse.jgit.nls.NLS, value: org.apache.felix.framework.BundleWiringImpl$BundleClassLoaderJava5 #14
>                 <- <class>     - class: org.eclipse.jgit.nls.NLS, value: org.eclipse.jgit.nls.NLS class NLS
>                  <- value     - class: java.lang.ThreadLocal$ThreadLocalMap$Entry, value: org.eclipse.jgit.nls.NLS #1
>                   <- [11]     - class: java.lang.ThreadLocal$ThreadLocalMap$Entry[], value: java.lang.ThreadLocal$ThreadLocalMap$Entry #144
>                    <- table     - class: java.lang.ThreadLocal$ThreadLocalMap, value: java.lang.ThreadLocal$ThreadLocalMap$Entry[] #1
>                     <- inheritableThreadLocals (thread object)     - class: java.lang.Thread, value: java.lang.ThreadLocal$ThreadLocalMap #2
> {noformat}



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)