ASP.NET Core 2.x Application acquired Memory and not collected by Garbage Collector - Free Memory used by ASP.NET Core Application
If your self hosted application acquired memory and it's not released then (or your asp.net core application lead to system out of memory), the tips in this post will help you. Once on my application what I had seen at the time of high traffic the memory acquired by ASP.NET Core application is not free and the server is running out of memory.
To fix this issue my team and me started to find the problem in the application and after some hour of profiling, what we had seen there is not a big issue in code but we are lacking some configurations. We got some tips to configure memory and CPU limit in IIS Pool. So we added this limit in the IIS Pool.
But actually what this limit dose, when the limit reaches for memory it will start Recycling IIS Pool. Images for the IIS Pool is shown above,
So this setting helped us to fix the server out of memory problem but this is not what we are looking for,
We want to free the memory without Recycling IIS Pool. So after reading a lot of thread in GitHub, we found a way to work around on it. The workaround is simple just a enable "System.GC.Server" setting to false. What this setting will do for us, it will change our Garbage collection mode from Server to WorkStation mode.
To enable this setting just Add this line in YourProjectName.csproj file under <PropertyGroup> section.
like
To enable this setting just Add this line in YourProjectName.csproj file under <PropertyGroup> section.
like
<PropertyGroup>
<ServerGarbageCollection>false</ServerGarbageCollection>
</PropertyGroup>
and then publish your application and deploy in the server.
What this setting will do in the publish file, it will add a file like
yourpjectname.runtimeconfig.json
and what we find in this json file is,
yourpjectname.runtimeconfig.json
and what we find in this json file is,
{
"runtimeOptions": {
"configProperties": {
"System.GC.Server": false
}
}
}
So this small line will do work to free memory acquired by YourProjectName.exe on Server. Hope this small setting will help someone whose, application has a problem of high memory uses in high traffic.
Some more tips [Best Practice for production], for hosting ASP.NET Core Application on Server,
If possible use
- Self-contained deployments (SCD)
- So if needed you can do run different version application on the same server and not have to think .NET versions. But using other deployments also have its own benefits like the size of the deployment package is small.
- Add <MvcRazorCompileOnPublish>false</MvcRazorCompileOnPublish> in <PropertyGroup> section to not publish MvcRazor as .dll,
- So that any HTML changes can be done without build and publish, but this one has it's own positive and negative side, but as a web developer it's good to have MvcRazorfile in place of .dll in my view.
- Proper use of in-memory Cache
- Use of Response Compression middleware like "app.UseResponseCompression()"
- Note for this you need to have a NuGet package like "Microsoft.AspNetCore.ResponseCompression": "1.0.0" or new one,
- Proper use of .css and .js bundling
- But Please think about HTTP-2 on some case you may not do bundling for everything.
- And if think for security, application firewall, etc. if you have to manage that too or not.
In coming days I will come with a full checklist for production deployments. Thank you for reading, If you have more points please add in commect so that other can get help with your ideas too.