Hi,
continuing on from
http://karaf.922171.n3.nabble.com/Multiple-restarts-effect-on-heap-and-Perm-Gen-memory-td4028550.html
I have put down a few points that may be of interest to other users re
permgen class loader leaks. For many this may be be old hat but thought it
might help.
-------------------------
1) There appears to be a memory leak in Karaf 2.2.5 (or the dependent
bundles) which no longer exists in Karaf 2.3.1 (I don't know about
intervening versions)
steps to recreate based on modifying the demonstration command bundle
packaged with Karaf:
In Karaf 2.2.5
a) modify the file
${karaf-install-dir}/demos/command/src/main/resources/OSGI-INF/blueprint/mycommand.xml
and add
<service ref="myCompleter"
interface="org.apache.karaf.demos.command.MyCompleter" />
b) Build the modified project e.g.
cd ${karaf-install-dir}/demos
mvn clean install
c) start karaf e.g.
cd ${karaf-install-dir}/bin
./karaf
d) install the modified demo command completer bundle
e.g. osgi:install -s
mvn:org.apache.karaf.demos/org.apache.karaf.demos.command/2.2.5 or (2.3.1)
e) Start JVisual VM, select karaf, right click and perform a heap dump
e.g. $JAVA_HOME/bin/jvisualvm&
f) Click on the classes tab and order the classes by class name (or perhaps
use OQL) and confirm that the class
org.apache.karaf.demos.command.MyCompleter is present with 1 instance
g) uninstall the bundle e.g.
osgi:uninstall 'Apache Karaf :: Demos :: Extend Console Command'
h) Repeat steps e) and f) and you will still see that an instance of class
org.apache.karaf.demos.command.MyCompleter is still present
Now repeat the above using Karaf 2.3.1 and after uninstalling the bundle you
will notice that there is no class
org.apache.karaf.demos.command.MyCompleter present
-------------------------
2) There appears to be issues with CGLIB and consequently libraries that use
CGLIB
a) Using Spring's @Transactional annotations without coding the services to
implement interfaces. Spring will use CGLIB and you will get a class loader
permgen leak each time you uninstall/install the bundle.
see https://jira.springsource.org/browse/SPR-8190 and
https://jira.springsource.org/browse/SPR-5654
I tried using Spring 3.2.2.RELEASE as suggested in the JIRAs above but still
got a memory leak. I also tried using compile time weaving but but still got
a memory leak.
Changing all the code to use interfaces fixed this particular issue.
b) Don't export the org.springframework.orm.jpa.JpaTransactionManager (or
other implementations of PlatformTransactionManager) but rather
org.springframework.transaction.PlatformTransactionManager as the later is
an interface where as JpaTransactionManager is a class which again will mean
CGLIB comes into play and you will get a class loader permgen leak each time
you uninstall/install the bundle that references the transaction manager.
-------------------------
3) When using activemq and camel don't export the
org.apache.camel.component.jms.JmsComponent or
org.apache.activemq.camel.component.ActiveMQComponent from the broker bundle
but rather the javax.jms.ConnectionFactory (as per Christian's tutorial
http://www.liquid-reality.de/display/liquid/2012/01/03/Karaf+Tutorial+Part+5+-+Running+Apache+Camel+integrations+in+OSGi)
then reference the javax.jms.ConnectionFactory in your 'client' bundle e.g.
(or the blueprint equivalent)
<reference id="connectionFactory"
interface="javax.jms.ConnectionFactory" />
<beans:bean id="jmsConfig"
class="org.apache.camel.component.jms.JmsConfiguration">
<beans:property name="connectionFactory" ref="connectionFactory"/>
.
</beans:bean>
<beans:bean id="jms"
class="org.apache.camel.component.jms.JmsComponent">
<beans:constructor-arg ref="jmsConfig"/>
</beans:bean>
If you export the org.apache.camel.component.jms.JmsComponent or
org.apache.activemq.camel.component.ActiveMQComponent from the broker bundle
and reference either from the client bundle e.g.
<reference id="jms"
interface="org.apache.camel.component.jms.JmsComponent"/>
you will get a class loader permgen leak each time you uninstall/install the
bundle.
-------------------------
I have also tried various combinations of sping-dm and blueprint for the
cases above and get the same issues for both.
I realise that class loader permgen leaks are an old well trodden issue that
came to the forefront when undeploying web apps but OSGI permits breaking an
application down into fine grained modules so I think this issue will become
even more apparent as the promise of undeploying/stopping/starting parts of
an application is a significant driver for the adoption of OSGI.
I am not sure of the implications of configuring camel/activemq to export
the JmsComponent/ActiveMQComponent from the broker bundle vs exporting
javax.jms.ConnectionFactory and creating a JmsComponent/ActiveMQComponent
bean in the referencing bundle, perhaps someone could comment?
Thanks,
Tim
--
View this message in context:
http://karaf.922171.n3.nabble.com/A-few-observations-about-permgen-class-loader-leaks-tp4028707.html
Sent from the Karaf - User mailing list archive at Nabble.com.