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