YangSiJun528 opened a new issue, #2424:
URL: https://github.com/apache/iggy/issues/2424
## Summary
Blocking TCP clients leak memory because they don't call `ByteBuf.release()`
after reading responses from `InternalTcpClient.send()`.
## Reproduction
Create and run the following test in the `java-sdk` module:
```java
class ByteBufMemoryLeakTest extends IntegrationTest {
@BeforeAll
static void setUpLeakDetector() {
ResourceLeakDetector.setLevel(ResourceLeakDetector.Level.PARANOID);
System.out.println("=== ByteBuf leak detection enabled (PARANOID
level) ===");
}
@Override
protected IggyBaseClient getClient() {
return TcpClientFactory.create(iggyServer);
}
@Test
void shouldNotLeakMemoryWhenPollingMessages() {
// given
login();
setUpStreamAndTopic();
var messagesClient = client.messages();
// Send test messages
for (int i = 0; i < 10; i++) {
messagesClient.sendMessages(
STREAM_NAME, TOPIC_NAME, Partitioning.partitionId(0L),
List.of(Message.of("leak-test-" + i)));
}
// when - Poll messages (this would leak ByteBufs if not properly
handled)
for (int i = 0; i < 2; i++) {
var polledMessages = messagesClient.pollMessages(
STREAM_NAME,
TOPIC_NAME,
empty(),
Consumer.of(0L),
new PollingStrategy(PollingKind.Last, BigInteger.TEN),
10L,
false);
}
// then - Force GC to trigger ResourceLeakDetector
System.gc();
}
}
```
Example code:
https://github.com/YangSiJun528/iggy/blob/netty-mem-leak/foreign/java/java-sdk/src/test/java/org/apache/iggy/client/blocking/tcp/ByteBufMemoryLeakTest.java
**Result:**
in console
```
ERROR io.netty.util.ResourceLeakDetector -- LEAK: ByteBuf.release() was not
called before it's garbage-collected.
Recent access records:
#1: TopicsTcpClient.createTopic(TopicsTcpClient.java:92)
BytesDeserializer.readTopicDetails(BytesDeserializer.java:88)
```
## Root Cause
The `InternalTcpClient.send()` method returns `ByteBuf` objects that must be
explicitly released.
Blocking TCP client implementations that use `InternalTcpClient`
(`StreamsTcpClient`, `SystemTcpClient`, `MessagesTcpClient`, etc.) do not call
`release()` on the returned `ByteBuf`, causing memory leaks.
## Proposed Solution
Update all blocking TCP client implementations to use `try-finally` blocks
that ensure `release()` is called:
```java
// Example: StreamsTcpClient.java
public List<UserInfo> getUsers() {
var response = tcpClient.send(CommandCode.User.GET_ALL);
try {
List<UserInfo> users = new ArrayList<>();
while (response.isReadable()) {
users.add(BytesDeserializer.readUserInfo(response));
}
return users;
} finally {
response.release();
}
}
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]