Native memory consumption of ASP.net core application #29521
-
Hi everyone. 👋 I lately did some profiling of our application we migrated to ASP.net core and I noticed quite a big memory consumption for an application like that. First I thought it is our fault because of some custom stuff we're doing, so I ran a memory profiler. But surprisingly it is not our managed code which is allocating this memory, but it is rather native memory that is consuming a lot of space. It is for me not yet sure if it is general ASP.net core or general .net related: Here the usual graph (left is after startup+force GC, right is after opening the landing page + force GC) 160MB native memory feels like a lot 😱. In order to find out where this is coming from, I was hoping if somebody can share some insights on what native memory ASP.net core applications might use. My Setup:
So far I have following candidates where I could think our application could use more memory:
A plain "Hello World" application crawls around at ~50MB in total which would be fine. As it is quite hard to find out what native memory is allocated and from where, I thought of reaching out to the community to get maybe some input. I will try to dig deeper in parallel with UMDH and some memory dump analysis tools we have but I fear it will be hard to dig out these details. Greetings |
Beta Was this translation helpful? Give feedback.
Replies: 5 comments 8 replies
-
@Maoni0 @jkotas any advice for a better understanding of memory usage here (this application is running on .NET Framework) ? Server GC is likely one reason for the memory usage and dynamic compilation. Using roslyn in process at runtime is likely a reason for high memory usage. |
Beta Was this translation helpful? Give feedback.
-
Update: The initial growth from 0 to ~80MB (with 54MB native memory) mainly seem to be caused by some assembly loading. I see a lot of allocates in relation to PE file (and PDB?) loading and some internal allocations. We have an overall of 163 assemblies in our project (22 System., 106 Microsoft., + our nuget and own dlls) which sum up to 32MB DLLs + 7MB PDBs on Disk. The second grow seems again loading a lot of assemblies, types, etc. Also some JIT compilation. Quite hard to judge for me if this is caused by ASP.net core specifics or .net in general. 😟 I have uploaded (parts) of the UMDH diffs to this gist: https://gist.github.com/Danielku15/c2139b453a66da62d529bfb3a745071c Somebody has an idea here? We have ~60 controllers in our project, and ~200 cshtml files (layouts, partials, views, all included) if this gives some indication. |
Beta Was this translation helpful? Give feedback.
-
Beta Was this translation helpful? Give feedback.
-
Good news on the native memory consumption. I was able to identify the main cause of it, it is really the Razor compilation.
So far I was playing with setting the MvcRazorCompileOn** to true or false and could not see a difference. But when removing the tags like described above, things changed! This is the memory consumption after removing the tags fully: Adding them again with "true" leads to: The yellow part is the part that stays the same. The red part is the additional cost of the Razor compilation. I would say the yellow consumption is on a level which is acceptable to an application of our size (based on gut-feeling). Now I will need to evaluate the risk of not being able to adjust razor files on demand in installations. It helps sometimes on error investigations. Best would be to have something "combined" where it uses the DLL by default and only compiles changes if needed. |
Beta Was this translation helpful? Give feedback.
-
I was able to improve the memory consumption to a reasonable level. To fully answer my initial question: The main memory consumption is coming from the Razor file compilation. We were not using any precompiled views befoer which caused Roslyn to load a lot of things and perform a lot of tasks which caused the load. It is unclear why this is detected as Native Memory, but it could be related to some dynamic PE file generation and loading happening there. To reduce the consumption without losing the possibility to dynamically change Razor templates following things needed to be changed:
<PropertyGroup>
<MvcRazorExcludeViewFilesFromPublish>false</MvcRazorExcludeViewFilesFromPublish>
<MvcRazorExcludeRefAssembliesFromPublish>false</MvcRazorExcludeRefAssembliesFromPublish>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.ViewCompilation" Version="2.2.0" />
</ItemGroup> Hope this helps others having similar issues. |
Beta Was this translation helpful? Give feedback.
I was able to improve the memory consumption to a reasonable level. To fully answer my initial question:
The main memory consumption is coming from the Razor file compilation. We were not using any precompiled views befoer which caused Roslyn to load a lot of things and perform a lot of tasks which caused the load. It is unclear why this is detected as Native Memory, but it could be related to some dynamic PE file generation and loading happening there.
To reduce the consumption without losing the possibility to dynamically change Razor templates following things needed to be changed: