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

[jsscripting] Potential memory leak #18224

Open
HolgerHees opened this issue Feb 4, 2025 · 3 comments · May be fixed by #18226
Open

[jsscripting] Potential memory leak #18224

HolgerHees opened this issue Feb 4, 2025 · 3 comments · May be fixed by #18226
Assignees
Labels
bug An unexpected problem or unintended behavior of an add-on

Comments

@HolgerHees
Copy link
Contributor

HolgerHees commented Feb 4, 2025

After I played with my own pythonscripting binding I found maybe a potential memory leak in your binding too.

The function OpenhabGraalJSScriptEngine.close is Override the function DelegatingScriptEngineWithInvocableAndCompilableAndAutocloseable.close()

That means that the close function there is never called and the delegate (GraalJSScriptEngine) is also never closed.

Maybe I'm missing something. That's why I'm posting my issues here to clarify whether I'm wrong.

@HolgerHees HolgerHees added the bug An unexpected problem or unintended behavior of an add-on label Feb 4, 2025
florian-h05 added a commit to florian-h05/openhab-addons that referenced this issue Feb 4, 2025
@florian-h05
Copy link
Contributor

Looks like you are right.
I haven't noticed an actual memory leak, but better to be on the safe side: #18226.

@HolgerHees
Copy link
Contributor Author

HolgerHees commented Feb 4, 2025

@florian-h05 I found out after this fix, that the lifecycle hook does not work anymore. Neither in jsscripting nor in pythonscripting

require('@runtime').lifecycleTracker.addDisposeHook(() => {
  console.log("Deinitialization hook runs...")
});

the context is closed, before the dispose hook is called.

The exception is then

2025-02-04 11:55:23.587 [ERROR] [ipt.internal.ScriptEngineManagerImpl] - Error removing ScriptEngine
java.lang.IllegalStateException: Multi threaded access requested by thread Thread[#705,OH-scriptwatcher-1,5,Configuration Admin Service] but is not allowed for language(s) js.
        at com.oracle.truffle.polyglot.PolyglotEngineException.illegalState(PolyglotEngineException.java:133) ~[?:?]
        at com.oracle.truffle.polyglot.PolyglotContextImpl.throwDeniedThreadAccess(PolyglotContextImpl.java:1408) ~[?:?]
        at com.oracle.truffle.polyglot.PolyglotContextImpl.checkAllThreadAccesses(PolyglotContextImpl.java:1060) ~[?:?]
        at com.oracle.truffle.polyglot.PolyglotContextImpl.enterThreadChanged(PolyglotContextImpl.java:881) ~[?:?]
        at com.oracle.truffle.polyglot.PolyglotEngineImpl.enterCached(PolyglotEngineImpl.java:2124) ~[?:?]
        at com.oracle.truffle.polyglot.HostToGuestRootNode.execute(HostToGuestRootNode.java:109) ~[?:?]
        at com.oracle.truffle.api.impl.DefaultCallTarget.call(DefaultCallTarget.java:104) ~[?:?]
        at com.oracle.truffle.polyglot.PolyglotFunctionProxyHandler.invoke(PolyglotFunctionProxyHandler.java:151) ~[?:?]
        at jdk.proxy25.$Proxy146.dispose(Unknown Source) ~[?:?]
        at org.openhab.core.automation.module.script.LifecycleScriptExtensionProvider$LifecycleTracker.dispose(LifecycleScriptExtensionProvider.java:93) ~[?:?]
        at org.openhab.core.automation.module.script.LifecycleScriptExtensionProvider.unload(LifecycleScriptExtensionProvider.java:80) ~[?:?]
        at org.openhab.core.automation.module.script.internal.ScriptExtensionManager.dispose(ScriptExtensionManager.java:142) ~[?:?]
        at org.openhab.core.automation.module.script.internal.ScriptEngineManagerImpl.removeScriptExtensions(ScriptEngineManagerImpl.java:232) ~[?:?]
        at org.openhab.core.automation.module.script.internal.ScriptEngineManagerImpl.removeEngine(ScriptEngineManagerImpl.java:226) ~[?:?]
        at org.openhab.core.automation.module.script.rulesupport.loader.AbstractScriptFileWatcher.lambda$13(AbstractScriptFileWatcher.java:304) ~[?:?]
        at java.util.concurrent.CompletableFuture$AsyncRun.run(Unknown Source) ~[?:?]
        at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) ~[?:?]
        at java.util.concurrent.FutureTask.run(Unknown Source) ~[?:?]
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source) ~[?:?]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) ~[?:?]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) ~[?:?]
        at java.lang.Thread.run(Unknown Source) [?:?]
        Suppressed: com.oracle.truffle.api.TruffleStackTrace$LazyStackTrace

my problem is that I depend on this hook, because I use it to cleanup python threads.

in pythonscripting the exception looks a bit different, it shows that the context was canceled before the hook is called.

2025-02-04 08:19:34.360 [ERROR] [ipt.internal.ScriptEngineManagerImpl] - Error removing ScriptEngine
org.graalvm.polyglot.PolyglotException: Context execution was cancelled.
        at <python>._clean(Unknown) ~[?:?]
        at com.oracle.truffle.polyglot.PolyglotFunctionProxyHandler.invoke(PolyglotFunctionProxyHandler.java:151) ~[?:?]
        at jdk.proxy24.$Proxy150.dispose(Unknown Source) ~[?:?]
        at org.openhab.core.automation.module.script.LifecycleScriptExtensionProvider$LifecycleTracker.dispose(LifecycleScriptExtensionProvider.java:93) ~[?:?]
        at org.openhab.core.automation.module.script.LifecycleScriptExtensionProvider.unload(LifecycleScriptExtensionProvider.java:80) ~[?:?]
        at org.openhab.core.automation.module.script.internal.ScriptExtensionManager.dispose(ScriptExtensionManager.java:142) ~[?:?]
        at org.openhab.core.automation.module.script.internal.ScriptEngineManagerImpl.removeScriptExtensions(ScriptEngineManagerImpl.java:232) ~[?:?]
        at org.openhab.core.automation.module.script.internal.ScriptEngineManagerImpl.removeEngine(ScriptEngineManagerImpl.java:226) ~[?:?]
        at org.openhab.core.automation.module.script.rulesupport.loader.AbstractScriptFileWatcher.lambda$13(AbstractScriptFileWatcher.java:304) ~[?:?]
        at java.util.concurrent.CompletableFuture$AsyncRun.run(Unknown Source) ~[?:?]
        at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) ~[?:?]
        at java.util.concurrent.FutureTask.run(Unknown Source) ~[?:?]
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source) ~[?:?]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) ~[?:?]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) ~[?:?]
        at java.lang.Thread.run(Unknown Source) [?:?]

@HolgerHees
Copy link
Contributor Author

HolgerHees commented Feb 4, 2025

I solved the followup lifecycleTracker problem by replacing the openhab lifecycleTracker in the ScriptContext with my own implementation which is called directly before the PythonScriptEngine.close

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug An unexpected problem or unintended behavior of an add-on
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants