247 Memory Puzzle with Lambdas

Author: Dr. Heinz M. Kabutz Date: 2017-03-31 Java Version: 8 Category: Performance

Abstract: Just like inner classes, lambdas might also suffer from memory issues, but to a lesser extent. In this puzzle you need to figure out which lambdas are affected.

Welcome to the 247th edition of The Java(tm) Specialists' Newsletter, sent to you from the beautiful Island of Crete. It is the season for wild asparagus, which grows naturally underneath olive trees on our mountains. Healthy, crunchy and delicious. Eaten raw or boiled. Even though most people come for the beaches, Crete has far more interesting food to offer at this time of year.

javaspecialists.teachable.com: Please visit our new self-study course catalog to see how you can upskill your Java knowledge.

Memory Puzzle with Lambdas

When someone with 315094 Twitter followers asks if I could post a Java puzzle, I am happy to oblige :) Here it is. Besides the "Hi from ... " messages, what other output do you see?

import java.util.concurrent.*; import static java.util.concurrent.TimeUnit.*; public class MemoryPuzzleWithLambdas { static class A { public Runnable get() { return new Runnable() { public void run() { System.out.println( "Hi from A" ); } }; } protected void finalize() throws Throwable { System.out.println( "A finalized" ); } } static class B { public Runnable get() { return () -> System.out.println( "Hi from B" ); } protected void finalize() throws Throwable { System.out.println( "B finalized" ); } } static class C { private int count = 0 ; public Runnable get() { return () -> System.out.println( "Hi from C #" + ++count); } protected void finalize() throws Throwable { System.out.println( "C finalized" ); } } static class D { private static int count = 0 ; public Runnable get() { return () -> System.out.println( "Hi from D #" + ++count); } protected void finalize() throws Throwable { System.out.println( "D finalized" ); } } static class E { private int count = ThreadLocalRandom.current().nextInt(); public Runnable get() { int count = this .count; return () -> System.out.println( "Hi from E " + count); } protected void finalize() throws Throwable { System.out.println( "E finalized" ); } } static class F { public Runnable get() { return this ::friendly; } public void friendly() { System.out.println( "Hi from F" ); } protected void finalize() throws Throwable { System.out.println( "F finalized" ); } } static class G { // Thanks Gray Watson for the suggestion public Runnable get() { return new MyRunnable(); } protected void finalize() { System.out.println( "G finalized" ); } private static class MyRunnable implements Runnable { public void run() { System.out.println( "Hi from G" ); } } } public static void main(String... args) { ScheduledExecutorService timer = Executors.newSingleThreadScheduledExecutor(); timer.scheduleAtFixedRate( new A().get(), 1 , 1 , SECONDS); timer.scheduleAtFixedRate( new B().get(), 1 , 1 , SECONDS); timer.scheduleAtFixedRate( new C().get(), 1 , 1 , SECONDS); timer.scheduleAtFixedRate( new D().get(), 1 , 1 , SECONDS); timer.scheduleAtFixedRate( new E().get(), 1 , 1 , SECONDS); timer.scheduleAtFixedRate( new F().get(), 1 , 1 , SECONDS); timer.scheduleAtFixedRate( new G().get(), 1 , 1 , SECONDS); timer.scheduleAtFixedRate(System::gc, 1 , 1 , SECONDS); } }

See if you can figure it out without first running the code :-)

Kind regards from Crete

Heinz

We are always happy to receive comments from our readers. Feel free to send me a comment via email or discuss the newsletter in our JavaSpecialists Slack Channel (Get an invite here)

Load Disqus comments

When you load these comments, you'll be connected to Disqus. Privacy Statement.

Please enable JavaScript to view the comments powered by Disqus.

Related Articles

195 Performance Puzzler with a Stack Trace 2011-09-15 In this newsletter, we present a little performance puzzler, written by Kirk Pepperdine. What is happening with this system? There is only one explanation and it can be discovered by just looking at the stack trace. Full Article

059 When Arguments Get out of Hand... 2002-11-11 We turn the dial to full blast and find out how many parameters a method may contain. Wholly impractical, but fun. Full Article

164 Why 0x61c88647? 2008-09-29 Prior to Java 1.4, ThreadLocals caused thread contention, rendering them useless for performant code. In the new design, each thread contains its own ThreadLocalMap, thus improving throughput. However, we still face the possibility of memory leaks due to values not being cleared out of the Thre... Full Article

Browse the Newsletter Archive