On 24.04.2015 09:56, Julian Foad wrote: > Hi Brane. > > I'm sure you would have first looked for ways to make this happen > automatically or not be needed. Is there anything you can report on > that front, for future reference?
You mean, apart from in the log message? The root of the "problem" lies in the way JavaHL wraps native objects within Java objects, by storing a pointer to the underlying native C++ object in a private variable of the Java object. Since Java doesn't have destructors and we can't reliably use the finalizer to clean up the native object, we invent a dispose() method that Java code must call when it's done using wrapper. This worked moderately well up to now. In the case of the status editor, the native code itself creates a Java stream to pass to the editor implementation and did not call the dispose method. Hence, the native object was never deallocated and heap usage kept growing. (Even though there's theoretically a mechanism in JavaHL to detect this, it's not always reliable, due to the way the JVM garbage collector works.) There were two options for a fix: * dispose of the object from the native code when it goes out of scope; or, * close the stream (causing an implicit disposal) from Java code. Picking the former would mean that the Java code must not close the stream, since doing so would result in a crash. Picking the latter means that forgetting to close the stream results in a memory leak. Faced with this dilemma, I decided that a potential memory leak with documented workaround is the less horrible option. FWIW, I only noticed this because the wrapped native object contains a pool that was never destroyed, and analyzing APR pool debug logs in combination with some stack trace generating magic finally pointed at the actual line of code that was the culprit. Without that, finding the missing 'delete' would be that much harder. Running the Java test program though Valgrind, for example, was an exercise in futility ... Valgrind never came close to noticing the leak, even with APR pool debugging enabled. -- Brane