Skip to content

[Bug] Memory was leaked by query when close sender before send WriteBatch. #321

Open

Description

@loserwang1024

Search before asking

  • I searched in the issues and found nothing similar.

Fluss version

0.5

Minimal reproduce step

Add test to SenderTest

    @Test
    void testRecycle() throws Exception {
        long offset = 0;
        CompletableFuture<Exception> future = new CompletableFuture<>();
        appendToAccumulator(tb1, row(DATA1_ROW_TYPE, new Object[] {1, "a"}), future::complete);
        sender.forceClose();
       // sender.runOnce();
}

What doesn't meet your expectations?

Throw exception:

java.lang.IllegalStateException: Memory was leaked by query. Memory leaked: (24576)
Allocator(ROOT) 0/24576/24576/9223372036854775807 (res/actual/peak/limit)


	at com.alibaba.fluss.shaded.arrow.org.apache.arrow.memory.BaseAllocator.close(BaseAllocator.java:477)
	at com.alibaba.fluss.shaded.arrow.org.apache.arrow.memory.RootAllocator.close(RootAllocator.java:29)
	at com.alibaba.fluss.client.write.RecordAccumulator.close(RecordAccumulator.java:908)
	at com.alibaba.fluss.client.write.Sender.initiateClose(Sender.java:539)
	at com.alibaba.fluss.client.write.Sender.forceClose(Sender.java:532)
	at com.alibaba.fluss.client.write.SenderTest.testSimple(SenderTest.java:99)

Anything else?

Currently, the arrowWriter is recycle in the following situations:

  1. when Sender#sendWriteData, invokes com.alibaba.fluss.record.MemoryLogRecordsArrowBuilder#trySerialize , the ArrowLogWriteBatch will arrowWriter.recycle(writerEpoch) of ArrowLogWriteBatch.
  2. when Sender is closed, sender#initiateClose -> accumulator#close ->arrowWriterPool#close will recycle the free arrowWriter.

It means that if close before Sender#sendWriteData, the non-free( hold by ArrowLogWriteBatch) arrowWriter won't be recycled.

Are you willing to submit a PR?

  • I'm willing to submit a PR!

Activity

  1. LiebingYu commented on Jul 30, 2025

    @LiebingYu
    Contributor

    Hi @loserwang1024. Wha's the progress about this ? I also meet this bug in Flink job.

    2025-07-30 16:42:18,191 [xxx[27]: Writer (153/1024)#63] INFO  com.alibaba.fluss.client.write.WriterClient                  [] - Closing writer.
    2025-07-30 16:42:18,192 [xxx[27]: Writer (153/1024)#63] ERROR com.alibaba.fluss.shaded.arrow.org.apache.arrow.memory.BaseAllocator [] - Memory was leaked by query. Memory leaked: (29574584)
    Allocator(ROOT) 0/29574712/29574712/9223372036854775807 (res/actual/peak/limit)
    
    2025-07-30 16:42:18,192 [xxx[27]: Writer (153/1024)#63] WARN  com.alibaba.fluss.flink.sink.writer.FlinkSinkWriter          [] - Exception occurs while closing Fluss Connection.
    java.lang.IllegalStateException: Memory was leaked by query. Memory leaked: (29574584)
    Allocator(ROOT) 0/29574712/29574712/9223372036854775807 (res/actual/peak/limit)
    
    	at com.alibaba.fluss.shaded.arrow.org.apache.arrow.memory.BaseAllocator.close(BaseAllocator.java:477) ~[blob_p-02e183c52725f33401961c6310dc5758b1e7e11d-6ff4e20658cfe414b942d44d5c607f1d:0.6-ali-3-SNAPSHOT]
    	at com.alibaba.fluss.shaded.arrow.org.apache.arrow.memory.RootAllocator.close(RootAllocator.java:29) ~[blob_p-02e183c52725f33401961c6310dc5758b1e7e11d-6ff4e20658cfe414b942d44d5c607f1d:0.6-ali-3-SNAPSHOT]
    	at com.alibaba.fluss.client.write.RecordAccumulator.close(RecordAccumulator.java:926) ~[blob_p-02e183c52725f33401961c6310dc5758b1e7e11d-6ff4e20658cfe414b942d44d5c607f1d:0.6-ali-3-SNAPSHOT]
    	at com.alibaba.fluss.client.write.Sender.initiateClose(Sender.java:600) ~[blob_p-02e183c52725f33401961c6310dc5758b1e7e11d-6ff4e20658cfe414b942d44d5c607f1d:0.6-ali-3-SNAPSHOT]
    	at com.alibaba.fluss.client.write.WriterClient.close(WriterClient.java:290) ~[blob_p-02e183c52725f33401961c6310dc5758b1e7e11d-6ff4e20658cfe414b942d44d5c607f1d:0.6-ali-3-SNAPSHOT]
    	at com.alibaba.fluss.client.FlussConnection.close(FlussConnection.java:180) ~[blob_p-02e183c52725f33401961c6310dc5758b1e7e11d-6ff4e20658cfe414b942d44d5c607f1d:0.6-ali-3-SNAPSHOT]
    	at com.alibaba.fluss.flink.sink.writer.FlinkSinkWriter.close(FlinkSinkWriter.java:180) ~[blob_p-02e183c52725f33401961c6310dc5758b1e7e11d-6ff4e20658cfe414b942d44d5c607f1d:0.6-ali-3-SNAPSHOT]
    	at org.apache.flink.util.IOUtils.closeAll(IOUtils.java:255) ~[ververica-connector-vvp-1.17-vvr-8.0.11-1-aidata-SNAPSHOT-jar-with-dependencies.jar:1.17-vvr-8.0.11-1-aidata-SNAPSHOT]
    	at org.apache.flink.util.IOUtils.closeAll(IOUtils.java:234) ~[ververica-connector-vvp-1.17-vvr-8.0.11-1-aidata-SNAPSHOT-jar-with-dependencies.jar:1.17-vvr-8.0.11-1-aidata-SNAPSHOT]
    	at org.apache.flink.util.IOUtils.closeAll(IOUtils.java:223) ~[ververica-connector-vvp-1.17-vvr-8.0.11-1-aidata-SNAPSHOT-jar-with-dependencies.jar:1.17-vvr-8.0.11-1-aidata-SNAPSHOT]
    	at org.apache.flink.streaming.runtime.operators.sink.SinkWriterOperator.close(SinkWriterOperator.java:249) ~[flink-dist-1.17-vvr-8.0.11-1-aidata-SNAPSHOT.jar:1.17-vvr-8.0.11-1-aidata-SNAPSHOT]
    	at org.apache.flink.streaming.runtime.tasks.StreamOperatorWrapper.close(StreamOperatorWrapper.java:163) ~[flink-dist-1.17-vvr-8.0.11-1-aidata-SNAPSHOT.jar:1.17-vvr-8.0.11-1-aidata-SNAPSHOT]
    	at org.apache.flink.streaming.runtime.tasks.RegularOperatorChain.closeAllOperators(RegularOperatorChain.java:125) ~[flink-dist-1.17-vvr-8.0.11-1-aidata-SNAPSHOT.jar:1.17-vvr-8.0.11-1-aidata-SNAPSHOT]
    	at org.apache.flink.streaming.runtime.tasks.StreamTask.closeAllOperators(StreamTask.java:1275) ~[flink-dist-1.17-vvr-8.0.11-1-aidata-SNAPSHOT.jar:1.17-vvr-8.0.11-1-aidata-SNAPSHOT]
    	at org.apache.flink.util.IOUtils.closeAll(IOUtils.java:255) ~[ververica-connector-vvp-1.17-vvr-8.0.11-1-aidata-SNAPSHOT-jar-with-dependencies.jar:1.17-vvr-8.0.11-1-aidata-SNAPSHOT]
    	at org.apache.flink.core.fs.AutoCloseableRegistry.doClose(AutoCloseableRegistry.java:72) ~[ververica-connector-vvp-1.17-vvr-8.0.11-1-aidata-SNAPSHOT-jar-with-dependencies.jar:1.17-vvr-8.0.11-1-aidata-SNAPSHOT]
    	at org.apache.flink.util.AbstractAutoCloseableRegistry.close(AbstractAutoCloseableRegistry.java:127) ~[ververica-connector-vvp-1.17-vvr-8.0.11-1-aidata-SNAPSHOT-jar-with-dependencies.jar:1.17-vvr-8.0.11-1-aidata-SNAPSHOT]
    	at org.apache.flink.streaming.runtime.tasks.StreamTask.cleanUp(StreamTask.java:1183) ~[flink-dist-1.17-vvr-8.0.11-1-aidata-SNAPSHOT.jar:1.17-vvr-8.0.11-1-aidata-SNAPSHOT]
    	at org.apache.flink.runtime.taskmanager.Task.lambda$restoreAndInvoke$1(Task.java:950) ~[flink-dist-1.17-vvr-8.0.11-1-aidata-SNAPSHOT.jar:1.17-vvr-8.0.11-1-aidata-SNAPSHOT]
    	at org.apache.flink.runtime.taskmanager.Task.runWithSystemExitMonitoring(Task.java:968) [flink-dist-1.17-vvr-8.0.11-1-aidata-SNAPSHOT.jar:1.17-vvr-8.0.11-1-aidata-SNAPSHOT]
    	at org.apache.flink.runtime.taskmanager.Task.restoreAndInvoke(Task.java:950) [flink-dist-1.17-vvr-8.0.11-1-aidata-SNAPSHOT.jar:1.17-vvr-8.0.11-1-aidata-SNAPSHOT]
    	at org.apache.flink.runtime.taskmanager.Task.doRun(Task.java:754) [flink-dist-1.17-vvr-8.0.11-1-aidata-SNAPSHOT.jar:1.17-vvr-8.0.11-1-aidata-SNAPSHOT]
    	at org.apache.flink.runtime.taskmanager.Task.run(Task.java:569) [flink-dist-1.17-vvr-8.0.11-1-aidata-SNAPSHOT.jar:1.17-vvr-8.0.11-1-aidata-SNAPSHOT]
    	at java.lang.Thread.run(Thread.java:879) [?:1.8.0_372]
    

    I think we can close() only after all the batches have been sent successfully. If you don't have time to fix this issue right now, I can take it over.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions