In dotnet-trace file that collect CPU consumption, what might be cause of huge consumption by System.Private.CoreLib?
Asked Answered
I

0

8

I am trying to find cause for high CPU usage of my app.

TL;DR

My relatively simple .Net6 API application consumes 100% of 1vCPU doing only ~20 requests (each ~100ms) per second (only 2 concurrent requests). dotnet-trace shows inconclusive bottlenecks.

Bit of context:

A .Net6, ASP API application. App runs in docker container on kubernetes cluster. It is in .Net6, and it has dedicated 1000m CPU (meaning 1 full vCPU).

In order to fulfill a request the app calls DB twice or thrice, and external APIs few times. The app does not have any heavy calculations (no image processing, no huge lists, etc.). Just awaited DB calls and API calls, some JSON serialization, HttpClient calls, etc.

The issue is, that 1 pod with dedicated 1000m CPU (1 vCPU) is handling about 200 requests per second, each request is about 100ms, meaning it handles only about 2 requests concurrently. Such load consumes almost 100% dedicated CPU, and new pods are created.

IMO, with majority of work being "waiting for DB or API to return data" my server (each pod) should handle about 10x more load.

dotnet-trace

I run dotnet-trace in my container, and I can't really understand the data. My code is responsible for less that 5% of total CPU consumption. Following functions consumes most of it:

enter image description here

ad 1. ~21% of CPU System.Reflection.Emit.DynamicMethod.CreateDelegate - what this might mean? With the following hint does it mean NewtonsoftJson compiles code every time it serialize something?

enter image description here

ad 2. ~13% of CPU `System.Runtime.Loader.AssemblyLoadContext.LoadFromAssemblyPath' - does it mean my program constantly loads some assemblies? Hint: enter image description here

ad 3. ~11% of CPU System.Threading.LowLevelLifoSemaphore.WaitForSignal - are semaphores so expensive in use? I use it like this:

private readonly SemaphoreSlim _mySemaphore = new SemaphoreSlim(1);
(...)
await _mySemaphore.WaitAsync();
(...)
finally
{
    _mySemaphore.Release();
}
Intensify answered 5/2, 2023 at 10:38 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.