-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Memory usage when using Mailkit in containers #57213
Comments
I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label. |
Tagging subscribers to this area: @bartonjs, @vcsjones, @krwq, @GrabYourPitchforks Issue DetailsDescriptionWhen using the Mailkit library for sending emails on containers we are seeing a drastic increase in memory consumed per email. This persists until the container runs out of memory and crashes. This issue was opened on the MailKit repo, but nothing was found in the library causing the issue. I would expect the GC to free up the memory after the email is sent instead of allowing the consumption to build up until the container crashes. Example code of sending emails - public async Task SendEmailAsync(string email, string subject, string htmlMessage) {
var emailMetadata = _tenantMetadata.Value.Email;
var message = new MimeMessage();
//Need a string here and not null otherwise the call is ambiguous
message.To.Add(new MailboxAddress(string.Empty, email));
message.From.Add(new MailboxAddress(emailMetadata.FromName, emailMetadata.FromAddress));
message.Subject = subject;
message.Body = new TextPart(TextFormat.Html) {
Text = htmlMessage
};
var additionalData = new LoggerState() {
{ "From", emailMetadata.FromAddress },
{ "To", email },
{ "Subject", subject },
{ "Smtp location", emailMetadata.Server },
{ "Smtp port", emailMetadata.Port.ToString() }
};
using var emailClient = new SmtpClient();
try {
_logger.LogInformation("Sending email message.", additionalData);
await emailClient.ConnectAsync(emailMetadata.Server, emailMetadata.Port);
emailClient.AuthenticationMechanisms.Remove("XOAUTH2");
await emailClient.SendAsync(message);
_logger.LogInformation("Email successfully sent.", additionalData);
} catch (Exception ex) {
ex.Data.Add("AdditonalData", additionalData);
_logger.LogError(ex, "Email failed to send", additionalData);
throw;
} finally {
await emailClient.DisconnectAsync(true);
}
} Configuration.NET Core 3.1 3.1.13 runtime x64 on Ubuntu 18.04.5 LTS. Not sure if it's specific to this configuration. Regression?Using the legacy SmtpClient functions as expected. Other informationNot validating the SSL certificate seems to fix this, but is not an option for me.
|
@mwalczyk81 is there any chance that you could capture a GC dump and share it with us? https://github.com/dotnet/diagnostics/blob/main/documentation/dotnet-gcdump-instructions.md |
I've set the area to Security as from the referenced issue it seems that the leak is specific to SSL certs on Linux. |
@adamsitnik based on the discussion in the MailKit issue, it sounds like it may have something to do with checking for certificate revocation. In other words, if the Apparently different servers result in different amount of leakage. I tested with gmail and saw only a small leak but afaict, it was not coming from MailKit. |
Unfortunately I wasn't able to replicate this on my local machine and don't have access to the containers where the issue happens. I'll reach out again to other team members to see if I can get any help on that. |
This issue has been automatically marked Please refer to our contribution guidelines for tips on what information might be required. |
Still working with our internal teams to recreate this and get memory dumps |
@adamsitnik is there a place I can transfer a large file? The dump I finally got is 222MB. |
@jstedfast do you happen to have any ideas on where these files could go? |
Dropbox or OneDrive? Not sure what the maintainers would prefer |
Any updates on this issue ? |
@Vandersteen, would you be able to provide either a self-contained repro (i.e. sources + dockerfile) or GC dump or full memory dump? We have tried to reproduce the leak in cert validation in the past without success. |
I believe these are related: #52577 Someone wrote a repro gist here: https://gist.github.com/MihaZupan/2e207c4c703272961b475e482e96afa3#file-certrevocationmemory-cs-L18-L30 Note: it might be dependent on the domain. We used mailkit to send emails to We only had issues on stg / prd We now used the
And our memory leaks are gone |
I took some time to check this using repro from #55672, I checked using after 5 minutes:
after 10 minutes:
The main item of importance are the second and third items from the bottom, between the two measurements, the total free space (i.e. memory kept around by the allocator, but not allocated by the application) is growing, while the amount of memory actively being used by the app is more or less steady. This is in line with @bartonjs's suspicion from #52577 (comment). The problem is that we likely have no way to affect this behavior, even calling One thing that still baffles me is how can the total free space grow, since we seem to pretty much just repeatedly allocate and later correctly free the certificate, so to my understanding this should not cause any sort of memory fragmentation which would prevent malloc from releasing more memory. cc: @wfurt |
Can you check counts on various safe handles related CRLs? I've seen similar patterns in the past where small chunks of memory were preventing consolidation and that pushed overall memory use up. You can try to add |
Looks like between iterations, there is not really much truly alive concerning certificates. No SafeX509Handles lying around: DumpHeap listing
So the memory is not being held from managed side (and even explicit GC.Collect has little impact on the observed mallinfo stats). The few |
Using essentially the same test program as linked above, I see essentially no variation in the total virtual memory size of the process on .NET 6.0 on Ubuntu 18.04 during 3000 serial calls to Two caveats to "essentially no variation":
Since this is consistent with @rzikm's findings, I don't see any other action for us to take. |
Description
When using the Mailkit library for sending emails on containers we are seeing a drastic increase in memory consumed per email. This persists until the container runs out of memory and crashes. This issue was opened on the MailKit repo, but nothing was found in the library causing the issue.
I would expect the GC to free up the memory after the email is sent instead of allowing the consumption to build up until the container crashes.
Example code of sending emails -
Configuration
.NET Core 3.1 3.1.13 runtime x64 on Ubuntu 18.04.5 LTS. Not sure if it's specific to this configuration.
Regression?
Using the legacy SmtpClient functions as expected.
Other information
Not validating the SSL certificate seems to fix this, but is not an option for me.
The text was updated successfully, but these errors were encountered: