Driver classes still not unloading in dev mode


i still struggle with my opc-ua driver using the ignition api. Even after changing the ResourceBundle unloading as described in an erlier post, it is not possible to change property files without restarting the complete gateway.
After checking my implementation i finally tracked the issue down to the implementation of AbstractDriver, which causes some leaks when restarting a driver.

A little hash dump analyzing (awesome feature of java…) shows that with every driver restart some references to the old instance stay active, thus preventing the gc from removing the driver. I attached a screenshot of the heap after ten times restarting the SimDriver.

I digged a little deeper and finally narrowed it down to the following:
A reference to the driver itself is stored in DriverContext.privateExecutionManagers and is not removed during driver shutdown.
The same happens with an instance of AbstractDriver.RedundancyStateListener which is referenced somewhere in a EventListenerList (not sure what happens to redundancy if it tries to wake up a dead driver class).

When removing this two references, the stale classes reduce to the last 12 and stay at this number. The leftover reference is a class called ‘RequestHealthMonitor’. Looks like there is a ThreadPool with 12 threads, which does not remove the reference to the Runnable until the thread is reused.

Beyond that the temporary class files under ignition_main_tmp (older than the last 12) are still not deleteable, even though there are no instances left. This behavior stops when BundleUtil is not used anymore. Deep inside the class loader a reference to the jar file is cached, that keeps the file opened.

I’m pretty sure that this behavior will not cause real problems (as long as drivers are not restarted every few minutes), but it might be a good idea to check the AbstractDriver implementation (even if its only to make life easier for api users).

Nice analysis. I’ll get this stuff cleaned up tomorrow. Thank you.

Ok, BundleUtil#remove(Class<?>), as discussed in the other thread, was only fixed recently and will be in the 7.4.2 release.

I’ve also cleaned up the leaked references you just discussed for that release as well. Thanks for your feedback.

A quick update:

I just found a very old bug report ( JAR file not closed after loading .properties file in ResourceBundle

At the end it says:
This has now been fixed. To avoid caching JarFiles in JarURLConnection
call URLConnection.setDefaultUseCaches(false) on any instance of
URLConnection before using the resource bundle.

Seems this behavior has not changed since 2000. If i do as advised and call setDefaultUseCaches(false) on a dummy URLConnection in ModuleHook.setup it’s eventually possible to delete the old temporary jar files.

Not that this is of any use, but at least it is clear what keeps the file open.