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
dotnet-dump makes process to double its used memory and fails #71472
In a Kubernetes environment, we have a process that normally consumes around 3.8 Gi.
When we run dotnet-dump collect, it causes the process to increase memory usage up to around 7.2 Gi.
Since we have a 6 Gi memory limit for the Pod, dotnet-dump cannot finish dump generation and fails with a System.IO.EndOfStreamException: Unable to read beyond the end of the stream exception.
If we set a higher memory limit, dotnet-dump collect succeeded, approximately doubling the used memory.
Is this expected behavior? Is it possible to make it just save the dump to the file without consuming more memory?
Reproduction Steps
Run dotnet-dump collect --process-id 1
Expected behavior
A dump file is created
Actual behavior
Dump file generation failed and the process may be crashed
changed the title [-]dotnet-dump makes process to double its used memory and fail[/-][+]dotnet-dump makes process to double its used memory and fails[/+]on Jun 30, 2022
@afilatov-st Thanks for the bug report! I do not believe that memory doubling is expected in this scenario (though some memory usage is expected). Dotnet-Dump sends an IPC command using a domain socket on Linux to the target process to collect a dump. The target process will then launch createdump as a child process to collect a dump of the parent process. When the memory is doubled - is it the target process's memory that increases, createdump, or dotnet-dump itself that uses the extra memory? @mikem8361@hoyosjs
@tommcdon thanks for the prompt response!
the crash happens pretty quickly, so I had to run the following script in a parallel session
while true
do
ps aux;
sleep 0.5;
done
it shows that the RSS of the target dotnet process is in its initial value of 3.6 Gb for around 5 seconds, then it quickly grows to 6.2 Gb before Kubernetes kills it.
Can you try a heap dump by add --type Heap to the dotnet-dump collect command line?
We think maybe when createdump is reading memory to write pages to the dump file that causes them to be "swapped" back in or read from the module files into the target process memory. A heap dump doesn't touch/read most of the module pages.
@tommcdon@hoyosjs Is there an eta for having heap analyzers fixed?
This doubling memory issue makes dotnet dump unusable in the required scenarios, like debugging why is there high memory, as k8s will kill the pod.
@ezgambac Even in the case this got improved (the change wasn't backed out; it's just flagged off since it will make commands like verifyheap in SOS fail), it will still force memory swapping and some growth since the dumper itself runs in the cgroup of the container. For OOM, there's other options that could work since they are started in the init process's context if you have access to the host.
@hoyosjs What do you suggest doing then for the scenario where the pod is running at 80% memory then?
We currently have dotnet monitor 6, which uses an older version of dotnet dump, but from what you are saying, even if we moved to latest, the dumper would generate enough extra memory that k8s will kill the process?
From following this thread, it seemed like the change @ezsilmar had significantly reduced the memory consumption by dotnet dump while getting a dump. Would this dump be analyzable by perfview/visual studio?
It's analyzable, but you might get tooling telling you that the heap is inconsistent. You need to deploy the app with DOTNET_DbgDisablePagemapUse=0 and this is only there in .NET 8. Do you have access to the host (node)?
Activity
[-]dotnet-dump makes process to double its used memory and fail[/-][+]dotnet-dump makes process to double its used memory and fails[/+]tommcdon commentedon Jun 30, 2022
@afilatov-st Thanks for the bug report! I do not believe that memory doubling is expected in this scenario (though some memory usage is expected). Dotnet-Dump sends an IPC command using a domain socket on Linux to the target process to collect a dump. The target process will then launch createdump as a child process to collect a dump of the parent process. When the memory is doubled - is it the target process's memory that increases, createdump, or dotnet-dump itself that uses the extra memory?
@mikem8361 @hoyosjs
afilatov-st commentedon Jun 30, 2022
@tommcdon thanks for the prompt response!
the crash happens pretty quickly, so I had to run the following script in a parallel session
it shows that the RSS of the target dotnet process is in its initial value of 3.6 Gb for around 5 seconds, then it quickly grows to 6.2 Gb before Kubernetes kills it.
afilatov-st commentedon Jun 30, 2022
For the context, the Docker image is based on
mcr.microsoft.com/dotnet/aspnet:6.0.5-bullseye-slim-amd64mikem8361 commentedon Jul 12, 2022
Can you try a heap dump by add
--type Heapto the dotnet-dump collect command line?We think maybe when createdump is reading memory to write pages to the dump file that causes them to be "swapped" back in or read from the module files into the target process memory. A heap dump doesn't touch/read most of the module pages.
afilatov-st commentedon Jul 12, 2022
--type Heapbehaves in the same way59 remaining items
ezgambac commentedon Oct 31, 2023
@tommcdon @hoyosjs Is there an eta for having heap analyzers fixed?
This doubling memory issue makes dotnet dump unusable in the required scenarios, like debugging why is there high memory, as k8s will kill the pod.
hoyosjs commentedon Oct 31, 2023
@ezgambac Even in the case this got improved (the change wasn't backed out; it's just flagged off since it will make commands like
verifyheapin SOS fail), it will still force memory swapping and some growth since the dumper itself runs in the cgroup of the container. For OOM, there's other options that could work since they are started in the init process's context if you have access to the host.ezgambac commentedon Oct 31, 2023
@hoyosjs What do you suggest doing then for the scenario where the pod is running at 80% memory then?
We currently have dotnet monitor 6, which uses an older version of dotnet dump, but from what you are saying, even if we moved to latest, the dumper would generate enough extra memory that k8s will kill the process?
From following this thread, it seemed like the change @ezsilmar had significantly reduced the memory consumption by dotnet dump while getting a dump. Would this dump be analyzable by perfview/visual studio?
hoyosjs commentedon Oct 31, 2023
It's analyzable, but you might get tooling telling you that the heap is inconsistent. You need to deploy the app with
DOTNET_DbgDisablePagemapUse=0and this is only there in .NET 8. Do you have access to the host (node)?Warn about dotnet-dump memory usage
Warn about dotnet-dump memory usage (#45841)