Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Instances of JavascriptObject are not being garbage collected #172

Open
javighawk opened this issue Oct 25, 2018 · 0 comments
Open

Instances of JavascriptObject are not being garbage collected #172

javighawk opened this issue Oct 25, 2018 · 0 comments

Comments

@javighawk
Copy link

I've experienced a couple of memory issues when using GMapsFX on an application that adds and removes markers and polygons to a map periodically. The number of instances of any class contained in this library keeps increasing (even though my application doesn't hold any references to them anymore) until there's no memory left. After checking with jvisualvm what the problem was, I found out that no instances of any class that extends from JavascriptObject (e.g., Marker, LatLong, etc) are getting garbage collected. That is because the WeakHashMap peerRegistry in JavascriptObject keeps a reference to each JavascriptObject forever. WeakHashMap will allow an entry to be garbage collected if there isn't a strong reference to its key. However, in this case, for each entry in the WeakHashMap, the value is containing a reference to the key (see the JavascriptObject constructors):

public class JavascriptObject {

    protected static Map<JSObject,JavascriptObject> peerRegistry = new WeakHashMap<>();
    protected JSObject jsObject;
...
    protected JavascriptObject( String type, String stringRepresentation ) {
        runtime = JavascriptRuntime.getInstance();
        variableName = getNextVariableName();
        runtime.execute( "var " + variableName + " = " + stringRepresentation );
        jsObject = runtime.execute(variableName);
        peerRegistry.put(jsObject, this);
    }

As per this question in StackOverflow, the entry won't get garbage collected if the value holds a reference to the key. This means that, even though my application doesn't hold a reference to the JavascriptObject anymore, this WeakHashMap does, and will always keep it.

One of the solutions is mentioned in that StackOverflow question, which would be having JavascriptObject hold a weak reference to jsObject:

public class JavascriptObject {

    protected WeakReference<JSObject> jsObject;
...
    protected JavascriptObject( String type, String stringRepresentation ) {
        runtime = JavascriptRuntime.getInstance();
        variableName = getNextVariableName();
        runtime.execute( "var " + variableName + " = " + stringRepresentation );
        jsObject = new WeakReference<>(runtime.execute(variableName));
        peerRegistry.put(jsObject, this);
    }

Another solution would be to switch the key and the value of the WeakHashMap:

    protected static Map<JavascriptObject, JSObject> peerRegistry = new WeakHashMap<>();

I do not know the reasons why that WeakHashMap is needed though, so I'm not sure if the latter solution would be feasible.

If anyone could confirm that this is correct that would be great. Thank you very much.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant