1

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
...
ccnlui
  • 91
  • 5
  • 2
    You should use the memory profiler to analyze the allocations. Since the JMX connection itself produces garbage while sending information to VisualVM, you will never see a flat line. Since you have a capturing lambda expression using variables from the surrounding context, it will never be a singleton. So it may produce garbage, unless Escape Analysis proves that the JIT generated code could work without allocating memory for it. You could force re-use by creating these objects outside the loop, but actually, it’s not worth the effort. As said, JXM itself produces garbage, more than the loop. – Holger May 06 '22 at 07:37
  • @Holger good point about using VisualVM – Peter Lawrey May 07 '22 at 06:56

1 Answers1

0

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

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130