PlaceholderAPI / Javascript-Expansion

Adds javascript placeholders
GNU General Public License v3.0
22 stars 24 forks source link

Memory leaks #73

Open MaxWainer opened 1 year ago

MaxWainer commented 1 year ago

If we take a look deeper into implementation, we will see that every placeholder request, simply creating new object of the engine which is generally unnecessary and destructive to GC.

Current code doing smth like that (nashorn):

import javax.script.ScriptException;

import org.openjdk.nashorn.api.scripting.NashornScriptEngineFactory;

public class Leak {
    public static void main(String[] args) throws ScriptException {
        var factory = new NashornScriptEngineFactory();
        while (true) {
            var engine = factory.getScriptEngine("--no-java");
            System.out.printf("Result: %s\n", engine.eval("1 + 1"));
        }
    }
}

if we take a look at getScriptEngine (https://github.com/openjdk/nashorn/blob/ab2542ea0f3decad033991916167dbce4a46f314/src/org.openjdk.nashorn/share/classes/org/openjdk/nashorn/api/scripting/NashornScriptEngineFactory.java#L233), we will see that it's create all the time new object, when we can just use one ScriptEngine for everything, simply rebinding all needed variables.

let's dump our little application and we will see that jdk.internal.ref.CleanerImpl$PhantomCleanableRef top consumer, when in NORMAL application, byte[] most time is top consumer. That's point on memory leak.

If you still doesn't believe, you can just dump via jmap and analyse it via Eclipse Memory Analyzer (https://www.eclipse.org/mat/)

Possible solutions? Do not create for each execution new engine/context