← PracticeIntermediatePipelines
The Leak That Was a Queue
Pull up the evidence one item at a time, commit to a diagnosis, and only then see the schedule that actually ran.
What was reported
The ingest service runs out of memory every six to nine hours and restarts. We have been hunting a leak for a week. Heap dumps are dominated by event objects, but every one of them is legitimately referenced — nothing is held by a listener that forgot to unsubscribe, no closure captures anything odd, and the profiler shows no growth in any cache. We raised the heap from 4GB to 12GB and it now OOMs every eighteen hours instead of every seven.
1BlockingQueue<Event> queue = new LinkedBlockingQueue<>(); // no capacity argument2 3// HTTP thread, 12k requests/second at peak4void ingest(Event e) {5 queue.put(e); // never blocks: the queue is unbounded6 respond(202); // "accepted" — we told them we have it7}8 9// 4 consumer threads10void consume() {11 while (running) {12 Event e = queue.take();13 enrichAndWrite(e); // ~440us each: two lookups and an insert14 }15}Evidence
Nothing here is labelled as relevant. Some of it is not.