'Chronicle-Queue: Why does busy-waiting tailer generate garbage when spinning (nothing to be read)?

I have a busy-waiting loop in which a tailer is constantly trying to read from a queue:

final Bytes<ByteBuffer> bbb = Bytes.elasticByteBuffer(MAX_SIZE, MAX_SIZE);

// Busy wait loop.
while (true) {
    tailer.readDocument(wire -> {
        wire.read().marshallable(m -> {
            m.read(DATA).bytes(bbb, true);
            long rcvAt = m.read(RCVAT).int64();

            System.out.println(rcvAt);
        });
    });
}

Why does this code generate garbage even when there is nothing to read from the queue?

Relevant JVM flags: -server -XX:InitialHeapSize=64m -XX:MaxHeapSize=64m

GC logs and memory profile:

VisualVM enter image description here

GC logs is flooded with logs like this:

...
[30.071s][info][gc     ] GC(1755) Pause Young (Normal) (G1 Evacuation Pause) 23M->6M(30M) 0.250ms
[30.084s][info][gc     ] GC(1756) Pause Young (Normal) (G1 Evacuation Pause) 23M->7M(30M) 0.386ms
[30.096s][info][gc     ] GC(1757) Pause Young (Normal) (G1 Evacuation Pause) 24M->7M(30M) 0.544ms
[30.109s][info][gc     ] GC(1758) Pause Young (Normal) (G1 Evacuation Pause) 24M->7M(30M) 0.759ms
[30.122s][info][gc     ] GC(1759) Pause Young (Normal) (G1 Evacuation Pause) 24M->7M(30M) 0.808ms
[30.135s][info][gc     ] GC(1760) Pause Young (Normal) (G1 Evacuation Pause) 24M->7M(30M) 0.937ms
...


Solution 1:[1]

You have capturing lambda. They hold a reference to the bbb and thus get created on every interation. You can store them in local variables outside the loop to avoid them being created each time.

I suggest using Flight Recorder as it uses far less garbage to monitor the application

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Peter Lawrey