<html xmlns:v="urn:schemas-microsoft-com:vml" 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:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
        {font-family:ConsolasHigh;
        panose-1:2 11 6 9 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0cm;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;
        mso-fareast-language:EN-US;}
pre
        {mso-style-priority:99;
        mso-style-link:"Préformaté HTML Car";
        margin:0cm;
        margin-bottom:.0001pt;
        font-size:10.0pt;
        font-family:"Courier New";}
span.PrformatHTMLCar
        {mso-style-name:"Préformaté HTML Car";
        mso-style-priority:99;
        mso-style-link:"Préformaté HTML";
        font-family:"Courier New";
        mso-fareast-language:FR;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-size:10.0pt;}
@page WordSection1
        {size:612.0pt 792.0pt;
        margin:70.85pt 70.85pt 70.85pt 70.85pt;}
div.WordSection1
        {page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="FR" link="#0563C1" vlink="#954F72" style="word-wrap:break-word">
<div class="WordSection1">
<p class="MsoNormal">Hi</p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><span lang="EN-US">I was wondering if there is an artificial memory footprint related to retained stack objects “by default” in Loom compared to common async flatMap sequence, because lambdas would capture only objects really needed for
 the “next step”.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">Example:<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">1) Sync (with Loom, but same issue with OS thread):<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal" style="background:white"><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:#0033B3;mso-fareast-language:FR">public class
</span><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:black;mso-fareast-language:FR">Main1
</span><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:#080808;mso-fareast-language:FR">{<br>
   </span><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:#0033B3;mso-fareast-language:FR">public static void
</span><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:#00627A;mso-fareast-language:FR">main</span><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:#080808;mso-fareast-language:FR">(</span><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:black;mso-fareast-language:FR">String</span><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:#080808;mso-fareast-language:FR">[]
 args) </span><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:#0033B3;mso-fareast-language:FR">throws
</span><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:black;mso-fareast-language:FR">ExecutionException</span><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:#080808;mso-fareast-language:FR">,
</span><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:black;mso-fareast-language:FR">InterruptedException
</span><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:#080808;mso-fareast-language:FR">{<br>
      </span><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:#0033B3;mso-fareast-language:FR">var
</span><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:black;mso-fareast-language:FR">executor
</span><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:#080808;mso-fareast-language:FR">=
</span><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:black;mso-fareast-language:FR">Executors</span><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:#080808;mso-fareast-language:FR">.<i>newVirtualThreadPerTaskExecutor</i>();<br>
      </span><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:#0033B3;mso-fareast-language:FR">var
</span><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:black;mso-fareast-language:FR">future
</span><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:#080808;mso-fareast-language:FR">=
</span><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:black;mso-fareast-language:FR">executor</span><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:#080808;mso-fareast-language:FR">.submit(() -> {<br>
         </span><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:#0033B3;mso-fareast-language:FR">try
</span><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:#080808;mso-fareast-language:FR">{<br>
            </span><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:black;mso-fareast-language:FR">System</span><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:#080808;mso-fareast-language:FR">.</span><i><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:#871094;mso-fareast-language:FR">out</span></i><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:#080808;mso-fareast-language:FR">.println(</span><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:#067D17;mso-fareast-language:FR">"Starting
 work"</span><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:#080808;mso-fareast-language:FR">);<br>
            </span><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:#0033B3;mso-fareast-language:FR">var
</span><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:black;mso-fareast-language:FR">bigBuffer
</span><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:#080808;mso-fareast-language:FR">=
</span><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:#0033B3;mso-fareast-language:FR">new byte</span><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:#080808;mso-fareast-language:FR">[</span><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:#1750EB;mso-fareast-language:FR">1024
</span><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:#080808;mso-fareast-language:FR">*
</span><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:#1750EB;mso-fareast-language:FR">1024
</span><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:#080808;mso-fareast-language:FR">*
</span><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:#1750EB;mso-fareast-language:FR">1024</span><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:#080808;mso-fareast-language:FR">];<br>
            </span><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:black;mso-fareast-language:FR">System</span><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:#080808;mso-fareast-language:FR">.</span><i><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:#871094;mso-fareast-language:FR">out</span></i><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:#080808;mso-fareast-language:FR">.println(</span><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:#067D17;mso-fareast-language:FR">"bigBuffer
 size: " </span><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:#080808;mso-fareast-language:FR">+
</span><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:black;mso-fareast-language:FR">bigBuffer</span><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:#080808;mso-fareast-language:FR">.</span><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:#871094;mso-fareast-language:FR">length</span><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:#080808;mso-fareast-language:FR">);<br>
            </span><i><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:#8C8C8C;mso-fareast-language:FR">// bigBuffer = null;<br>
            </span></i><i><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:#080808;mso-fareast-language:FR">slowIO</span></i><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:#080808;mso-fareast-language:FR">();<br>
         } </span><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:#0033B3;mso-fareast-language:FR">catch
</span><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:#080808;mso-fareast-language:FR">(</span><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:black;mso-fareast-language:FR">InterruptedException
</span><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:#080808;mso-fareast-language:FR">e) {<br>
            </span><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:#0033B3;mso-fareast-language:FR">throw new
</span><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:#080808;mso-fareast-language:FR">RuntimeException(e);<br>
         }<br>
      });<br>
      </span><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:black;mso-fareast-language:FR">future</span><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:#080808;mso-fareast-language:FR">.get();<br>
   }<br>
<br>
   </span><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:#0033B3;mso-fareast-language:FR">private static void
</span><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:#00627A;mso-fareast-language:FR">slowIO</span><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:#080808;mso-fareast-language:FR">()
</span><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:#0033B3;mso-fareast-language:FR">throws
</span><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:black;mso-fareast-language:FR">InterruptedException
</span><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:#080808;mso-fareast-language:FR">{<br>
      </span><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:black;mso-fareast-language:FR">System</span><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:#080808;mso-fareast-language:FR">.</span><i><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:#871094;mso-fareast-language:FR">out</span></i><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:#080808;mso-fareast-language:FR">.println(</span><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:#067D17;mso-fareast-language:FR">"Starting
 slowIO"</span><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:#080808;mso-fareast-language:FR">);<br>
      </span><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:black;mso-fareast-language:FR">Thread</span><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:#080808;mso-fareast-language:FR">.<i>sleep</i>(</span><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:black;mso-fareast-language:FR">Long</span><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:#080808;mso-fareast-language:FR">.</span><i><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:#871094;mso-fareast-language:FR">MAX_VALUE</span></i><span lang="EN-US" style="font-size:10.0pt;font-family:ConsolasHigh;color:#080808;mso-fareast-language:FR">);<br>
   }<br>
}<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">2) Async (</span><span lang="EN-US" style="font-family:ConsolasHigh;color:black">CompletableFuture)</span><span lang="EN-US">:<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<pre style="background:white"><span lang="EN-US" style="font-family:ConsolasHigh;color:#0033B3">public class </span><span lang="EN-US" style="font-family:ConsolasHigh;color:black">Main2 </span><span lang="EN-US" style="font-family:ConsolasHigh;color:#080808">{<br>   </span><span lang="EN-US" style="font-family:ConsolasHigh;color:#0033B3">public static void </span><span lang="EN-US" style="font-family:ConsolasHigh;color:#00627A">main</span><span lang="EN-US" style="font-family:ConsolasHigh;color:#080808">(</span><span lang="EN-US" style="font-family:ConsolasHigh;color:black">String</span><span lang="EN-US" style="font-family:ConsolasHigh;color:#080808">[] args) </span><span lang="EN-US" style="font-family:ConsolasHigh;color:#0033B3">throws </span><span lang="EN-US" style="font-family:ConsolasHigh;color:black">ExecutionException</span><span lang="EN-US" style="font-family:ConsolasHigh;color:#080808">, </span><span lang="EN-US" style="font-family:ConsolasHigh;color:black">InterruptedException </span><span lang="EN-US" style="font-family:ConsolasHigh;color:#080808">{<br>      </span><span lang="EN-US" style="font-family:ConsolasHigh;color:#0033B3">var </span><span lang="EN-US" style="font-family:ConsolasHigh;color:black">future </span><span lang="EN-US" style="font-family:ConsolasHigh;color:#080808">= </span><span lang="EN-US" style="font-family:ConsolasHigh;color:black">CompletableFuture</span><span lang="EN-US" style="font-family:ConsolasHigh;color:#080808">.<i>runAsync</i>(() -> {<br>               </span><span lang="EN-US" style="font-family:ConsolasHigh;color:black">System</span><span lang="EN-US" style="font-family:ConsolasHigh;color:#080808">.</span><i><span lang="EN-US" style="font-family:ConsolasHigh;color:#871094">out</span></i><span lang="EN-US" style="font-family:ConsolasHigh;color:#080808">.println(</span><span lang="EN-US" style="font-family:ConsolasHigh;color:#067D17">"Starting work"</span><span lang="EN-US" style="font-family:ConsolasHigh;color:#080808">);<br>               </span><span lang="EN-US" style="font-family:ConsolasHigh;color:#0033B3">var </span><span lang="EN-US" style="font-family:ConsolasHigh;color:black">bigBuffer </span><span lang="EN-US" style="font-family:ConsolasHigh;color:#080808">= </span><span lang="EN-US" style="font-family:ConsolasHigh;color:#0033B3">new byte</span><span lang="EN-US" style="font-family:ConsolasHigh;color:#080808">[</span><span lang="EN-US" style="font-family:ConsolasHigh;color:#1750EB">1024 </span><span lang="EN-US" style="font-family:ConsolasHigh;color:#080808">* </span><span lang="EN-US" style="font-family:ConsolasHigh;color:#1750EB">1024 </span><span lang="EN-US" style="font-family:ConsolasHigh;color:#080808">* </span><span lang="EN-US" style="font-family:ConsolasHigh;color:#1750EB">1024</span><span lang="EN-US" style="font-family:ConsolasHigh;color:#080808">];<br>               </span><span lang="EN-US" style="font-family:ConsolasHigh;color:black">System</span><span lang="EN-US" style="font-family:ConsolasHigh;color:#080808">.</span><i><span lang="EN-US" style="font-family:ConsolasHigh;color:#871094">out</span></i><span lang="EN-US" style="font-family:ConsolasHigh;color:#080808">.println(</span><span lang="EN-US" style="font-family:ConsolasHigh;color:#067D17">"bigBuffer size: " </span><span lang="EN-US" style="font-family:ConsolasHigh;color:#080808">+ </span><span lang="EN-US" style="font-family:ConsolasHigh;color:black">bigBuffer</span><span lang="EN-US" style="font-family:ConsolasHigh;color:#080808">.</span><span lang="EN-US" style="font-family:ConsolasHigh;color:#871094">length</span><span lang="EN-US" style="font-family:ConsolasHigh;color:#080808">);<br>            }).thenCompose(x -> <i>slowIO</i>());<br>      </span><span lang="EN-US" style="font-family:ConsolasHigh;color:black">future</span><span lang="EN-US" style="font-family:ConsolasHigh;color:#080808">.get();<br>   }<br><br>   </span><span lang="EN-US" style="font-family:ConsolasHigh;color:#0033B3">private static </span><span lang="EN-US" style="font-family:ConsolasHigh;color:black">CompletableFuture</span><span lang="EN-US" style="font-family:ConsolasHigh;color:#080808"><?> </span><span lang="EN-US" style="font-family:ConsolasHigh;color:#00627A">slowIO</span><span lang="EN-US" style="font-family:ConsolasHigh;color:#080808">()  {<br>      </span><span lang="EN-US" style="font-family:ConsolasHigh;color:black">System</span><span lang="EN-US" style="font-family:ConsolasHigh;color:#080808">.</span><i><span lang="EN-US" style="font-family:ConsolasHigh;color:#871094">out</span></i><span lang="EN-US" style="font-family:ConsolasHigh;color:#080808">.println(</span><span lang="EN-US" style="font-family:ConsolasHigh;color:#067D17">"Starting slowIO"</span><span lang="EN-US" style="font-family:ConsolasHigh;color:#080808">);<br>      </span><span lang="EN-US" style="font-family:ConsolasHigh;color:#0033B3">return new </span><span lang="EN-US" style="font-family:ConsolasHigh;color:#080808">CompletableFuture<>();<br>   }<br>}<o:p></o:p></span></pre>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">In the sync case, the big buffer is retained in heap during the slow IO (until it eventually returns), even if it’s not needed anymore.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">This problem doesn’t exist in the Async scenario since the slow IO step has not captured the big buffer.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">A workaround is to explicitly set the var to null, but I wonder if there could be a better way… could the JVM do that automatically?<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">(I imagine it may be against the current JVM spec to allow garbage-collection of an unreferenced stack var early before the end of its method, even if it’s unused at a point in the method execution.)<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">Thanks<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US">Arnaud<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p>
</div>

<DIV>
Unless otherwise stated above:<BR>
<BR>
Compagnie IBM France<BR>
Siège Social : 17, avenue de l'Europe, 92275 Bois-Colombes Cedex<BR>
RCS Nanterre 552 118 465<BR>
Forme Sociale : S.A.S.<BR>
Capital Social : 664 069 390,60 €<BR>
SIRET : 552 118 465 03644 - Code NAF 6203Z<BR>
</DIV></body>
</html>