Late cleanup of stack objects

Arnaud Masson arnaud.masson at fr.ibm.com
Sat Nov 5 15:33:12 UTC 2022


Hi

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”.

Example:

1) Sync (with Loom, but same issue with OS thread):

public class Main1 {
   public static void main(String[] args) throws ExecutionException, InterruptedException {
      var executor = Executors.newVirtualThreadPerTaskExecutor();
      var future = executor.submit(() -> {
         try {
            System.out.println("Starting work");
            var bigBuffer = new byte[1024 * 1024 * 1024];
            System.out.println("bigBuffer size: " + bigBuffer.length);
            // bigBuffer = null;
            slowIO();
         } catch (InterruptedException e) {
            throw new RuntimeException(e);
         }
      });
      future.get();
   }

   private static void slowIO() throws InterruptedException {
      System.out.println("Starting slowIO");
      Thread.sleep(Long.MAX_VALUE);
   }
}

2) Async (CompletableFuture):


public class Main2 {
   public static void main(String[] args) throws ExecutionException, InterruptedException {
      var future = CompletableFuture.runAsync(() -> {
               System.out.println("Starting work");
               var bigBuffer = new byte[1024 * 1024 * 1024];
               System.out.println("bigBuffer size: " + bigBuffer.length);
            }).thenCompose(x -> slowIO());
      future.get();
   }

   private static CompletableFuture<?> slowIO()  {
      System.out.println("Starting slowIO");
      return new CompletableFuture<>();
   }
}

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.
This problem doesn’t exist in the Async scenario since the slow IO step has not captured the big buffer.
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?
(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.)

Thanks
Arnaud



Unless otherwise stated above:

Compagnie IBM France
Siège Social : 17, avenue de l'Europe, 92275 Bois-Colombes Cedex
RCS Nanterre 552 118 465
Forme Sociale : S.A.S.
Capital Social : 664 069 390,60 €
SIRET : 552 118 465 03644 - Code NAF 6203Z
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/loom-dev/attachments/20221105/098c0743/attachment-0001.htm>


More information about the loom-dev mailing list