You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Backport Fix memory leak with OptionsMonitor #868 to .NET Core 2.1 #3552
Issue
Currently there is a memory leak in using OptionsMonitor in .NET Core 2.1 and this has been fixed as part of .NET Core 3.0 and above. (#868)
Solution
Given .NET Core 2.1 has LTS support until 21-08-2021, is it possible to backport this fix to .NET Core 2.1
Alternatives considered
There is no alternative other than upgrading to .NET Core 3.1 and we have a lot of dependencies that needs to be considered which is not going to help us to resolve the memory leak issue in a timely fashion.
How did you reproduce the issue? This particular one required multiple host instantiations and disposals. Did you track down what caused the problem in your case?
We had multiple app services hosting this API on Azure and we noticed the memory leak behavior with the the implementation of OptionsMonitor and OnChange event and when I commented invoking the OnChange event the memory leak stopped.
Were you spinning up multiple instances of the host in a single process? The reason I'm asking these questions is because that PR fixes a very specific issue that would be hard to reproduce without doing something atypical.
The API is called 'n' number of times as part of the CertificateAuthenticationHandler once per request. Every CertificateAuthenticationHandler registers itself to the OptionsMonitor.OnChange event.
Why is there a finalizer? Make the CertificateAuthenticationHandler implement IDisposable and call _listener.Dispose in the Dispose method. That should solve your problem.
Even better would be to use IOptionsSnapshot<T> to get the current snapshot of options (assuming this service is scoped or transient). That would resolve the lifetime mismatch going on here.
Activity
davidfowl commentedon Sep 22, 2020
Did you run into this? If so where?
shantha05 commentedon Sep 22, 2020
Yes, we are using .NET Core 2.1 API hosted on Azure and we are seeing the memory leak behavior there.
davidfowl commentedon Sep 22, 2020
How did you reproduce the issue? This particular one required multiple host instantiations and disposals. Did you track down what caused the problem in your case?
shantha05 commentedon Sep 22, 2020
We had multiple app services hosting this API on Azure and we noticed the memory leak behavior with the the implementation of OptionsMonitor and OnChange event and when I commented invoking the OnChange event the memory leak stopped.
davidfowl commentedon Sep 22, 2020
@shantha05 were you disposing the
IDisposablereturned from OnChange in your scenario and it was still leaking?shantha05 commentedon Sep 22, 2020
Yes, it was also tried and still it was leaking memory
davidfowl commentedon Sep 22, 2020
Were you spinning up multiple instances of the host in a single process? The reason I'm asking these questions is because that PR fixes a very specific issue that would be hard to reproduce without doing something atypical.
shantha05 commentedon Sep 22, 2020
We had 2 different App Services in 2 resource groups hosted in 2 locations and routing traffic using Traffic Manager so it's 2 different processes
davidfowl commentedon Sep 22, 2020
Then I don't see how that specific PR fixes the issue you're describing. Can you show the code snippet of the leak?
shantha05 commentedon Sep 22, 2020
This is the code that was commented to stop the memory leak.
productsOptions.OnChange((config) => {
_productSettings = config;
});
where productOptions is IOptionsMonitor productsOptions
davidfowl commentedon Sep 22, 2020
How often did you call OnChange? Once per application? Or once per request? Where is the code that stores the result and disposed it
shantha05 commentedon Sep 22, 2020
The API is called 'n' number of times as part of the CertificateAuthenticationHandler once per request. Every CertificateAuthenticationHandler registers itself to the OptionsMonitor.OnChange event.
davidfowl commentedon Sep 22, 2020
Can you show the registration and disposal code?
shantha05 commentedon Sep 22, 2020
davidfowl commentedon Sep 22, 2020
Why is there a finalizer? Make the
CertificateAuthenticationHandlerimplement IDisposable and call _listener.Dispose in the Dispose method. That should solve your problem.davidfowl commentedon Sep 22, 2020
Even better would be to use IOptionsSnapshot<T> to get the current snapshot of options (assuming this service is scoped or transient). That would resolve the lifetime mismatch going on here.
shantha05 commentedon Sep 22, 2020
Thanks David. Let me give that a try