High CPU consumption with Java-21 + Nashorn 15.4

Packiaraj S s.packiaraj at gmail.com
Fri Nov 1 18:38:51 UTC 2024


Thanks Attila. This is the side-effect of Unsafe.defineAnonymousClass
removal changes.

Just a thought. If script Engine can be shared across threads, would it be
possible to make the script ClassCache global, like making classCache
<https://github.com/openjdk/nashorn/blob/main/src/org.openjdk.nashorn/share/classes/org/openjdk/nashorn/internal/runtime/Context.java#L387>
as
static. That way cache is reused across threads and performance is also
improved. I tried this solution and it seems to be working fine, but
unfortunately due to Licensing (GPL v2) I am unable to make source code
changes.

On Fri, Nov 1, 2024 at 10:48 AM Attila Szegedi <szegedia at gmail.com> wrote:

> 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/ea4064b3/attachment.htm>


More information about the nashorn-dev mailing list