Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -268,14 +268,17 @@ public Deque<ProducerBatch> split(int splitBatchSize) {
// A newly created batch can always host the first message.
if (!batch.tryAppendForSplit(record.timestamp(), record.key(), record.value(), record.headers(), thunk)) {
batches.add(batch);
batch.closeForRecordAppends();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

batch.closeForRecordAppends does NOT release the byte array hosted by MemoryRecordsBuilder

    public void closeForRecordAppends() {
        if (appendStream != CLOSED_STREAM) {
            try {
                appendStream.close();
            } catch (IOException e) {
                throw new KafkaException(e);
            } finally {
                appendStream = CLOSED_STREAM;
            }
        }
    }

appendStream is a wrap of bufferStream. Not sure whether calling batch.closeForRecordAppends() can resolve the OOM or not.

this.appendStream = new DataOutputStream(compressionType.wrapForOutput(this.bufferStream, magic));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@chia7712 Thanks for reporting the issue. But I'd like to understand this problem a bit more. Supposedly the split batches will be closed when they are drained out of the RecordAccumulator.
https://github.com/apache/kafka/blob/trunk/clients/src/main/java/org/apache/kafka/clients/producer/internals/RecordAccumulator.java#L608

and ProducerBatch#close() calls ProducerBatch#closeForRecordAppends().

Do you have a heap dump when the OOM happens so we can take a further look?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@becketqin In my case, the OOM is caused by negative estimatedCompressionRatio. I have committed #8285 to fix it.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We probably also want to close the last batch for append in line 279.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@becketqin My negligence! The last batch should also be closed. I have modified it.

batch = createBatchOffAccumulatorForRecord(record, splitBatchSize);
batch.tryAppendForSplit(record.timestamp(), record.key(), record.value(), record.headers(), thunk);
}
}

// Close the last batch and add it to the batch list after split.
if (batch != null)
if (batch != null) {
batches.add(batch);
batch.closeForRecordAppends();
}

produceFuture.set(ProduceResponse.INVALID_OFFSET, NO_TIMESTAMP, new RecordBatchTooLargeException());
produceFuture.done();
Expand Down