OSGi is a Java framework that facilitates the development and deployment of modular software programs. It enables us to build larger applications from very loosely-coupled components. It improves the way Java classes interact within a single JVM using Java classloaders by encapsulating references to other codes in the same JVM in a well-defined architecture.
The framework maintains a registry of components known as bundles that represent each loaded jar file. The bundle, in turn, contains a custom classloader to load classes from its jar file. OSGi classloaders follow a peer-based approach. Each bundle exposes the classes that the jar file wants to expose and only uses the classes exposed by other peer jar files.
A bundle update operation results in a new classloader for the updated bundle - that is, first stopping the bundle, updating it to the new version and then restarting it using the new version. When a jar file of a bundle is loaded, the OSGi framework instantiates a bundle object, and that in turn creates a new classloader.
Reloading or redeploying a bundle within the framework could lead to classloader leaks. Each time you update a bundle, a new classloader becomes responsible for loading the classes. At the same time, the old classloader stays unused. Since the old classloader doesn't have any reference, it should be available for garbage collection. However, if the old classloader is still reachable from one or more references, it cannot be garbage collected - hence introducing a classloader leak. This leads to unnecessary consumption of memory resources in metaspace or Java heap.
In this session, we will analyse such classloader leaks – why they happen, how to find and troubleshoot them. It is based on experiences acquired over the years in analysing a commercial OSGi application performing regular bundle updates. Furthermore, this session will provide you with an overview of how to debug your OSGi application for such leaks using popular tools such as Eclipse Memory Analyzer Tool (MAT) and YourKit.