High CPU consumption with Java-21 + Nashorn 15.4
Attila Szegedi
szegedia at gmail.com
Fri Nov 1 17:48:14 UTC 2024
Hi Packiaraj,
I suspect a particular issue might be at play here. Specifically, Nashorn
used to be able to rely on Unsafe.defineAnonymousClass to use a more
lightweight method to load compiled code. This was unfortunately taken away
with Java 17. You can test this assumption by running your system on Java
16 and see whether the performance gets restored. Unfortunately, there's
not much we can do to fix that. Nashorn will use
Unsafe.defineAnonymousClass when available, but on Java 17+ it is no longer.
However, you can, in fact, share ScriptEngine instances across threads, and
you should prepare all your scripts into CompiledScript instances if you
can. What you shouldn't share is Bindings. I wrote about this in some
detail in this SO answer: https://stackoverflow.com/a/30159424/131552, and
also less comprehensively here: https://stackoverflow.com/a/34122641/131552
Hope this helps.
Attila.
On Fri, Oct 25, 2024 at 5:21 PM Packiaraj S <s.packiaraj at gmail.com> wrote:
> Hello,
>
> We use Nashorn with Tomcat as a long running service. We recently
> migrated to Java 21. ( from java 11 and the performance is good
> with Java-11).
> Since Nashorn is moved out of JDK we have pulled in '
> *nashorn-core-15.4.jar*' and its dependency (*asm**) and loaded it as a
> regular jar. Functionality everything looks ok.
>
> During the performance test we observed very high cpu usage when nashorn
> engine's 'eval' is called. The CPU consumption is so high that instances
> are throttled and performance becomes 10x slower compared to java-11.
>
> Upon investigation using profiler (jvisualVM) looks like most of the CPU
> is spent in compile method
> <https://github.com/openjdk/nashorn/blob/main/src/org.openjdk.nashorn/share/classes/org/openjdk/nashorn/internal/runtime/Context.java#L1454>,
> more specifically during ContextCodeInstaller.initialize
> <https://github.com/openjdk/nashorn/blob/main/src/org.openjdk.nashorn/share/classes/org/openjdk/nashorn/internal/runtime/Context.java#L217>
> and NamedContextCodeInstaller.install
> <https://github.com/openjdk/nashorn/blob/main/src/org.openjdk.nashorn/share/classes/org/openjdk/nashorn/internal/runtime/Context.java#L290>
>
>
> Looks like the compile method is optimized with cache, unfortunately the
> cache is in context scope, meaning it's not shared between ScriptEngines
> and Nashorn is not thread-safe (as per the docs) to use a single instance
> of ScriptEngine across all threads. Also the cache uses 'soft-reference',
> would it cause double whammy when there is a memory pressure.
>
> so, how to improve the performance of the Nashorn engine, specifically the
> `compile` part.
> Is there any other option we can try? BTW, persistent-code-cache did not
> help as OptimisticTypesPersistence.getVersionDirName is performing poorly
>
> Test code that we used to study this high CPU issue is attached.
>
> Thanks a lot for hemp & any insight
> Sakkanan
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/nashorn-dev/attachments/20241101/fdb93868/attachment.htm>
More information about the nashorn-dev
mailing list