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:
The common pattern for listening for events is to get either or injected into your component, then call so that any local methods with the or 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 and implement . In this method, you should unregister yourself from the event publisher via .
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 as described above.