Question on Lambda function

Zhengyu Gu zhengyu.gu at servicenow.com
Wed May 29 16:34:37 UTC 2024


Hello Lambda experts,

Since we upgraded JDK from 11 to 17, we’re experiencing metaspace pressure, largely due to Lambda class implementation changes.

There’s a scenario (see attached test case),  that is especially puzzled me, hopefully, you can share some insights.

In this test case, there is only one Lambda class is created inside the loop, but each one for the same functions outside loop.

Example output:

0: Func =  LambdaFunc$$Lambda/0x00001f80000c4a20 at 4de8b406
testMethod() called
1: Func =  LambdaFunc$$Lambda/0x00001f80000c4a20 at 4de8b406
testMethod() called
2: Func =  LambdaFunc$$Lambda/0x00001f80000c4a20 at 4de8b406
testMethod() called
3: Func =  LambdaFunc$$Lambda/0x00001f80000c4a20 at 4de8b406
testMethod() called
4: Func =  LambdaFunc$$Lambda/0x00001f80000c4a20 at 4de8b406
testMethod() called

….

Outside loop1, Func =  LambdaFunc$$Lambda/0x00001f80000c4c58 at 402f32ff
testMethod() called
Outside loop2 Func = LambdaFunc$$Lambda/0x00001f80000d1000 at 5ae9a829
testMethod() called
Outside loop3 Func = LambdaFunc$$Lambda/0x00001f80000d1238 at 548b7f67
testMethod() called

And jcmd also confirmed there were 4 Lambda classes created:

  49: CLD 0x000060000134cb50: "app" instance of jdk.internal.loader.ClassLoaders$AppClassLoader
      Loaded classes:
         1:    LambdaFunc$$Lambda/0x00001f80000d1238
         2:    LambdaFunc$$Lambda/0x00001f80000d1000
         3:    LambdaFunc$$Lambda/0x00001f80000c4c58
         4:    LambdaFunc$$Lambda/0x00001f80000c4a20
         5:    LambdaFunc

Looking into bytecode, all four call sites have the same invokedynamic bytecode (invokedynamic #7,  0              // InvokeDynamic #0:run:()Ljava/lang/Runnable; ) and the first invokedynamic bytecode is inside the loop.

But when I ran the program with -XX:+TraceBytecodes, it seems that the first invokedynamic was hoisted and result was used in the subsequence loop.

Can anyone explain where this magic happens?  If the magic can apply to the instances outside the loop, so that only one Lambda class is created?


Thank you for your time and expertise,

-Zhengyu



-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/core-libs-dev/attachments/20240529/80713643/attachment-0001.htm>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: LambdaFunc.java
Type: application/octet-stream
Size: 936 bytes
Desc: LambdaFunc.java
URL: <https://mail.openjdk.org/pipermail/core-libs-dev/attachments/20240529/80713643/LambdaFunc-0001.java>


More information about the core-libs-dev mailing list