| <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> |
| <html> |
| <head> |
| <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> |
| <title>The Equinox Project - Dynamic plugins</title> |
| <link rel="stylesheet" title="default" href="http://eclipse.org/default_style.css" type="text/css"> |
| </head> |
| <body> |
| <table BORDER=0 CELLSPACING=5 CELLPADDING=2 WIDTH="100%" > |
| <tr> |
| <td ALIGN=left width="60%"> |
| <p><font class=indextop> equinox</font><br> |
| <font class=indexsub> dynamic plugins > managing classloaders and instances </font> </p> |
| </td> |
| <td WIDTH="40%"> </td> |
| </tr> |
| </table> |
| <table border=0 cellspacing=5 cellpadding=2 width="100%" > |
| <tr> |
| <td align=LEFT valign=TOP colspan="2" bgcolor="#0080C0"><b><font color="#FFFFFF"> |
| Discussions</font></b></td> |
| </tr> |
| </table> |
| Essentially, deactivating a plugin P is a two-step process. First, the registry |
| asks the plugin to shutdown and then it releases its class loader. The registry |
| keeps a soft reference on the class loader in case the plugin would be |
| activated again before the class loader is actually garbage collected. |
| The plugin shutdown is necessary for the plugin class loader to have |
| a chance to go away. |
| <p></p><p> |
| When shutdown, a plugin must cleanup after object references that it leaked. |
| Indeed, for the class loader to go away and effectively releasing JVM-level |
| resources, all leaked |
| references must be cleaned up. A leak reference is a reference from an |
| outside object to an inside one. An inside object is a class loaded by |
| the class loader of plugin P or an instance of such a class. |
| An outside object is an instance of a class that is not loaded by |
| the class loader of P. |
| <br> |
| Note: if a plugin has started background threads, these threads |
| are roots of persistence for the garbage collector and should |
| therefore be stopped. Otherwise, the class loader will not be |
| garbage and will not be reclaimed, defeating the deactivation process. |
| </p><p> |
| So, what does it mean to be a good-citizen plugin? |
| Plugins need to track cross-plugin references and be |
| able to clean them up. Let's discuss and categorize |
| cross-plugin references. |
| </p><p> |
| Between class loaders, |
| we have two very different categories of Java reference: |
| type reference and instance references. Both are a Java |
| reference from an object to another, but the holder of |
| the reference is a Class object in the type reference |
| case where it is not a Class object in the instance |
| reference. |
| <BR> |
| The reason we differentiate them is that |
| object references can be cut while type references |
| cannot---they represent dependencies between loaded classes. |
| So if we have at type reference from a class loaded by plugin |
| P to a class loaded by plugin Q, the class loader of Q |
| will not go away until the class loader of P does. |
| This means that we cannot deactivate plugin Q |
| until we deactivate plugin P. This is of course a transitive |
| process along the inversed "require" graph. |
| <br> |
| <font color="magenta">Pascal:<br> |
| This is not a problem because Q can not |
| be deactivated if P is not.<br> |
| Olivier: Agreed, this is what the text says. |
| </font> |
| </p><p> |
| From a type reference perspective, as long as |
| someone has such a reference, the plugin with the referenced |
| class cannot be deactivated. So in other words, a plugin |
| can only be deactivated once all plugins requiring him |
| (transitively) are deactivated. This is something the registry |
| can do, once those plugins are shutdown and should have |
| cleaned up their leaked object references. |
| </p><p> |
| One of the most common object reference between plugins is |
| a reference on an extension object. Most extension objects |
| are short lived... so automated garbage collection should |
| still work. But not all extension objects are short-lived, |
| such as a view or markers for example. But unfortunately, |
| there is no life-cycle on extension objects, so |
| in general, a plugin does not know if the extension objects |
| it created are still used or not. |
| <br> |
| For a plugin to know if it can be deactivated, it would |
| have to keep track of those extension objects. |
| </p><p> |
| The next common object reference between plugins is leaked |
| references directly to other plugins such as SWT toolbars |
| or menus. These references are leaked directly, not through |
| the plugin registry. Here, we need plugins to maintain the knowledge |
| of those leaked references and to be able to clean them up |
| when no extension objects are still in use... |
| </p><p> |
| <font color="#FF0000"> |
| So to summarize, we need to add a life-cycle management for |
| extension objects. When a plugin has no active extension objects, |
| it could be asked to deactivate, that is, cleanup leaked |
| references... and stop all background threads. |
| This is unfortunately not very transparent and will not work |
| well with existing plugins. |
| <BR> |
| It will work, that is, class loaders will get collected, for |
| plugins not leaking object references or doing a good job |
| at scoping them to live extension objects. We may be fortunate. |
| </font> |
| </p><p> |
| So in the above scheme, plugins know when they are no |
| longer used (actively speaking: no active extension |
| objects). But we should probably not be too aggressive |
| regarding deactivation... |
| Most plugins are probably without active extensions |
| most of the time. So we could monitor activities on the extensions |
| of plugins... and if no one has asked for the creation of any extension |
| of a plugin in a given period of time, the registry could ask the plugin |
| to deactivate. If the plugin knows that it has no active extension objects, then |
| it can cleanup its other leaked object references. |
| </p><p> |
| At that stage, as far as the plugin is concerned, it is deactivated. |
| Its class loader will only go away when all class loaders holding type |
| references to some of its classes will go away. This will only happen |
| if their plugin has been deactivated or not yet activated. Here we |
| see that the plugin registry has to maintain this information and |
| not unnecessarily ask plugins to deactivate if other plugins |
| requiring it are not deactivated themselves. |
| </p><p> |
| This is a good start if we assume plugins designed properly and |
| behave correctly. This correct behavior is required on both side |
| of the extension mechanism... in order to track life extension |
| points correctly. The most widely spread mechanism to keep track |
| of such things is a dispose method. Second to an explicit dispose |
| method is reference counting. Third is proxying. All have their |
| pros and cons. |
| </p><p> |
| <font color="#FF0000"> |
| Do we all agree so far? |
| What do we do in failure cases, where plugins do not cleanup well |
| after themselves? Also, depending on which mechanism is used to |
| keep track of live extension objects, we may have more failure |
| scenarii. |
| </font></p> |
| <p> </p> |
| </body> |
| </html> |