Preventing Memory Leaks on Upgrades
Whether you need to be able to develop quickly via dynamic plugin installation or want to repeatedly upgrade a plugin on a production instance with no downtime, you will need to know how to prevent memory leaks from forcing a restart.
The core issue behind upgrade-related memory leaks is strong references by classes or objects outside your plugin to classes or objects loaded by your plugin. For example, if a Confluence object had a hard reference to one of your classes, whenever your plugin was upgraded, the plugin's classloader couldn't be garbage collected because there would still exist a strong reference to it via the referred object's class. The following are common causes of these types of memory leaks:
Lingering Event Registrations
The common pattern for listening for events is to get either
EventPublisher injected into your component, then call
eventPublisher.register(this) so that any local methods with the
@EventListener annotation will be called when events are published. However, this introduces a strong reference to your plugin class, as the event publisher sits outside your plugin down in the host application.
The solution is to implement
org.springframework.beans.factory.DisposableBean and implement
dispose(). In this method, you should unregister yourself from the event publisher via
Forgotten Job Registrations
If your plugin has registered any code to be called regularly via the job engine, ensure that you clean up that job when the plugin is shutdown. This shutdown code should go in a component that implements
DisposableBean as described above.