[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

Re: 1.9 JavaHL memory leak in ISVNRemote#status

From: Branko Čibej <brane_at_wandisco.com>
Date: Fri, 24 Apr 2015 10:15:09 +0200

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
Received on 2015-04-24 10:15:42 CEST

This is an archived mail posted to the Subversion Dev mailing list.

This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.