<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Windows-1252">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
{font-family:Aptos;
panose-1:2 11 0 4 2 2 2 2 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0in;
font-size:11.0pt;
font-family:"Aptos",sans-serif;}
.MsoChpDefault
{mso-style-type:export-only;
font-size:11.0pt;
mso-ligatures:none;}
@page WordSection1
{size:8.5in 11.0in;
margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
{page:WordSection1;}
--></style>
</head>
<body lang="EN-US" link="#467886" vlink="#96607D" style="word-wrap:break-word">
<div class="WordSection1">
<div id="mail-editor-reference-message-container">
<div>
<div>
<p class="MsoNormal"><span style="font-family:"Arial",sans-serif;color:#222222;background:white">Hello Lambda experts,</span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:12.0pt;font-family:"Arial",sans-serif;color:#222222"> </span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:12.0pt;font-family:"Arial",sans-serif;color:#222222">Since we upgraded JDK from 11 to 17, we’re experiencing metaspace pressure, largely due to Lambda class implementation changes.</span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:12.0pt;font-family:"Arial",sans-serif;color:#222222"> </span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:12.0pt;font-family:"Arial",sans-serif;color:#222222">There’s a scenario (see attached test case), that is especially puzzled me, hopefully, you can share some insights.</span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:12.0pt;font-family:"Arial",sans-serif;color:#222222"> </span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:12.0pt;font-family:"Arial",sans-serif;color:#222222">In this test case, there is only one Lambda class is created inside the loop, but each one for the same functions outside loop.</span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:12.0pt;font-family:"Arial",sans-serif;color:#222222"> </span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:12.0pt;font-family:"Arial",sans-serif;color:#222222">Example output:</span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:12.0pt;font-family:"Arial",sans-serif;color:#222222"> </span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:12.0pt;font-family:"Arial",sans-serif;color:#222222">0: Func = LambdaFunc$$Lambda/0x00001f80000c4a20@4de8b406</span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:12.0pt;font-family:"Arial",sans-serif;color:#222222">testMethod() called</span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:12.0pt;font-family:"Arial",sans-serif;color:#222222">1: Func = LambdaFunc$$Lambda/0x00001f80000c4a20@4de8b406</span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:12.0pt;font-family:"Arial",sans-serif;color:#222222">testMethod() called</span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:12.0pt;font-family:"Arial",sans-serif;color:#222222">2: Func = LambdaFunc$$Lambda/0x00001f80000c4a20@4de8b406</span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:12.0pt;font-family:"Arial",sans-serif;color:#222222">testMethod() called</span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:12.0pt;font-family:"Arial",sans-serif;color:#222222">3: Func = LambdaFunc$$Lambda/0x00001f80000c4a20@4de8b406</span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:12.0pt;font-family:"Arial",sans-serif;color:#222222">testMethod() called</span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:12.0pt;font-family:"Arial",sans-serif;color:#222222">4: Func = LambdaFunc$$Lambda/0x00001f80000c4a20@4de8b406</span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:12.0pt;font-family:"Arial",sans-serif;color:#222222">testMethod() called</span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:12.0pt;font-family:"Arial",sans-serif;color:#222222"> </span><o:p></o:p></p>
<p class="MsoNormal">….<o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:12.0pt"> </span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:12.0pt">Outside loop1, Func = LambdaFunc$$Lambda/0x00001f80000c4c58@402f32ff</span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:12.0pt">testMethod() called</span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:12.0pt">Outside loop2 Func = LambdaFunc$$Lambda/0x00001f80000d1000@5ae9a829</span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:12.0pt">testMethod() called</span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:12.0pt">Outside loop3 Func = LambdaFunc$$Lambda/0x00001f80000d1238@548b7f67</span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:12.0pt">testMethod() called</span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:12.0pt"> </span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:12.0pt">And jcmd also confirmed there were 4 Lambda classes created:</span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:12.0pt"> </span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:12.0pt"> 49: CLD 0x000060000134cb50: "app" instance of jdk.internal.loader.ClassLoaders$AppClassLoader</span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:12.0pt"> Loaded classes:</span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:12.0pt"> 1: LambdaFunc$$Lambda/0x00001f80000d1238</span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:12.0pt"> 2: LambdaFunc$$Lambda/0x00001f80000d1000
</span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:12.0pt"> 3: LambdaFunc$$Lambda/0x00001f80000c4c58</span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:12.0pt"> 4: LambdaFunc$$Lambda/0x00001f80000c4a20</span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:12.0pt"> 5: LambdaFunc</span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:12.0pt"> </span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:12.0pt">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.</span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:12.0pt"> </span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:12.0pt">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.</span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:12.0pt"> </span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:12.0pt">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?</span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:12.0pt"> </span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:12.0pt"> </span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:12.0pt">Thank you for your time and expertise,</span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:12.0pt"> </span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:12.0pt">-Zhengyu</span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:12.0pt"> </span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:12.0pt"> </span><o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:12.0pt"> </span><o:p></o:p></p>
</div>
</div>
</div>
</div>
</body>
</html>