Wafeelka
Wafeelka

Reputation: 67

Memory leak when I put message from Kafka to list of string

I have a memory leak when I consume from kafka topic and put message into a simple list

More details: I created a simple web api empty, where i have hosted service. Inside the hosted service i have a infinity loop which every 15 second repeat some simple action (Request to topic to back a new records and put record into a list). After this the hosted service wait 15 seconds and repeat this actions again.

The problem is every HostedService Loop a memory increase and never free. I did some cases like: 1)Turn off a method list.Add(record); and memory leak was gone. But wait a 2 case 2) I create a simple string and put example message like into kafka topic, and put this message into list. Memory leak didnt happened, but if i put a string whith a got from consumer.Consume().Message.Value a memory leak heppened with my app. I tried before every consume loop call list.Clear(). also tried use after using construction call GC.Collect(). And i tried to wrote this before the conume loop: list = null; All this things can't help. Can you help me with that?

Also, in snapshot i see what list was clear after consume but memory doesnt free image

How to reproduce Create a hosted service and into a loop try consume message and put into a list() a several times.

My hosted service:

public class HostedMailsFromKafkaSender : BackgroundService
{

    private readonly ILogger _logger;
    private readonly IKafkaSender _kafkaSender;
    public HostedMailsFromKafkaSender(IKafkaSender sender, ILogger logger)
    {
        _kafkaSender = sender;
        _logger = logger;
    }

    protected override async Task ExecuteAsync(CancellationToken cancellationToken)
    {
        await Task.Delay(5000, cancellationToken);

        while (!cancellationToken.IsCancellationRequested)
        {
            try
            {
                _kafkaSender?.SendMails();

            }
            catch (Exception e)
            {
                _logger.LogCritical(e, "Send error");
            }
            await Task.Delay(TimeSpan.FromSeconds(15), cancellationToken);
        }
    }
}

My kafka consume logic

public List ReadFromTopic(string topic)
{
List mailListTest = new();
var consumerConfig = new ConsumerConfig();
config.GetSection("Kafka:ConsumerSettings").Bind(consumerConfig);
using (var _consumer = new ConsumerBuilder<string, string>(consumerConfig).Build())
{
try
{
_consumer.Subscribe(topic);

                while (true)
                {
                    var consumeResult = _consumer.Consume(10000);
                     if (consumeResult.IsPartitionEOF)
                        break;

                     //tried wihtout this cast.Same thing
                    var encodingBytesRecord = Encoding.UTF8.GetBytes(consumeResult.Message.Value.ToString());
                    var record = Encoding.UTF8.GetString(encodingBytesRecord);
                    try
                    {
                        mailListTest.Add(record); 
                    }
                    catch (Exception ex)
                    {
                       
                    }
                }
                return null;
            }
            catch (Exception ex)
            {
                return null;
            }
        }
    }

My DI registration:

public void ConfigureServices(IServiceCollection services)
{
services.AddTransient<IKafkaSender, KafkaSender>();
services.AddHostedService();
services.AddControllers();
}

Confluent.Kafka nuget version. 1.9.2

My consumer settings: "AutoOffsetReset": "Earliest", "EnableAutoCommit": "false", "EnablePartitionEof": "true", "Topic": "", "BootstrapServers": "", "SslKeystorePassword": "", "SslCaLocation": "", "SecurityProtocol": "Ssl", "MaxPollIntervalMs": 600000

Operating system: tested on windows 10 and centOS 8

Also i used in dotMemory and saw this picture. For some reason a memory increased in GetString method enter image description here

I maked a issue for kafka library (https://github.com/confluentinc/confluent-kafka-dotnet/issues/1888), but i think the problem in my app

UPD

I'm currently testing one case: I added an example variable and put the text from 1 kafka record into the variable. The next step is to put that string variable into the list for example 27000 times (for example there are 27000 entries in kafka) and everything was fine. Problem inside casting kafka message type (probably not ordinary "string") to string type in dotnet

Upvotes: 0

Views: 997

Answers (1)

Wafeelka
Wafeelka

Reputation: 67

enter image description here In issue on github a user with nickname "albertherd" wrote this: " I suspect that this is an issue with GC.

Well, not an issue really. I guess you're stumbling GC in Server Mode. -> https://learn.microsoft.com/en-us/dotnet/standard/garbage-collection/workstation-server-gc

This video explains it in very good way -> [link]https://www.youtube.com/watch?v=y7FTxAqExyU "

I added an environment variable from this video (on my .Net 5 project its "COMPlus_gcServer": "0") and its helps i guess. Hothever in a diagram and in task manager i see what a memory doesn't increase. Probably its not the best way for this, because the app calling GC so many times, but still, its works for me now

Upvotes: -1

Related Questions