Large unexplained memory in the memory dump of a .NET process
I can't explain most of the memory used by a C# process. The total memory is 10 GB, but the total reachable and unreachable objects altogether total 2.5 GB. I wonder what these 7.5 GB could be?
I'm looking for the most likely explanations or a method to find out what this memory can be.
Here is the precise situation. The process is .NET 4.5.1. It downloads pages from internet and process them with machine learning. The memory is almost entirely in the Managed Heap as shown by VMMap. This seems to rule out unmanaged memory leak.
The process has been running for days and the memory slowly grew. At some point, the memory is 11 GB. I stop everything running in the process. I run garbage collections including large object heap compaction several times (with one minute of interval):
GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce;
GC.Collect();
The memory goes down to 10 GB. Then I create the dump:
procdump -ma psid
The dump is 10 GB as expected.
I open the dump with .NET memory profiler (version 5.6). The dump shows a total of 2.2 GB reachable objects and 0.3 GB unreachable objects. What could explain the remaining 7.5 GB ?
Possible explanations I've been thinking of :
- the LOH does not really get fully compacted
- some memory is used beyond the objects displayed by the profiler
c# memory-profiling large-object-heap
|
show 1 more comment
I can't explain most of the memory used by a C# process. The total memory is 10 GB, but the total reachable and unreachable objects altogether total 2.5 GB. I wonder what these 7.5 GB could be?
I'm looking for the most likely explanations or a method to find out what this memory can be.
Here is the precise situation. The process is .NET 4.5.1. It downloads pages from internet and process them with machine learning. The memory is almost entirely in the Managed Heap as shown by VMMap. This seems to rule out unmanaged memory leak.
The process has been running for days and the memory slowly grew. At some point, the memory is 11 GB. I stop everything running in the process. I run garbage collections including large object heap compaction several times (with one minute of interval):
GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce;
GC.Collect();
The memory goes down to 10 GB. Then I create the dump:
procdump -ma psid
The dump is 10 GB as expected.
I open the dump with .NET memory profiler (version 5.6). The dump shows a total of 2.2 GB reachable objects and 0.3 GB unreachable objects. What could explain the remaining 7.5 GB ?
Possible explanations I've been thinking of :
- the LOH does not really get fully compacted
- some memory is used beyond the objects displayed by the profiler
c# memory-profiling large-object-heap
2
This is kind of equivalent to "got memory leak, plz fix.". What does your service do? Does it call into anything unmanaged? Does it use COM?
– fstam
Nov 17 '18 at 10:43
3
You should not have that many unreachable objects after a GC. A deadlocked finalizer thread causes memory explosions, use WinDbg to see what it is doing.
– Hans Passant
Nov 17 '18 at 10:44
Thanks Hans. This unreachable memory was indeed suspicious to me. I'll have a look.
– Benoit Sanchez
Nov 17 '18 at 11:35
1
Sounds like unmanaged memory usage. The JetBrains profiler can show that. You could also use the free VMMap.exe to test that theory.
– usr
Nov 17 '18 at 14:08
Thanks usr. I checked with VMMap. 95% of my 10 GB are in the managed heap. This seems to rule out unmanaged memory usage.
– Benoit Sanchez
Nov 17 '18 at 19:48
|
show 1 more comment
I can't explain most of the memory used by a C# process. The total memory is 10 GB, but the total reachable and unreachable objects altogether total 2.5 GB. I wonder what these 7.5 GB could be?
I'm looking for the most likely explanations or a method to find out what this memory can be.
Here is the precise situation. The process is .NET 4.5.1. It downloads pages from internet and process them with machine learning. The memory is almost entirely in the Managed Heap as shown by VMMap. This seems to rule out unmanaged memory leak.
The process has been running for days and the memory slowly grew. At some point, the memory is 11 GB. I stop everything running in the process. I run garbage collections including large object heap compaction several times (with one minute of interval):
GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce;
GC.Collect();
The memory goes down to 10 GB. Then I create the dump:
procdump -ma psid
The dump is 10 GB as expected.
I open the dump with .NET memory profiler (version 5.6). The dump shows a total of 2.2 GB reachable objects and 0.3 GB unreachable objects. What could explain the remaining 7.5 GB ?
Possible explanations I've been thinking of :
- the LOH does not really get fully compacted
- some memory is used beyond the objects displayed by the profiler
c# memory-profiling large-object-heap
I can't explain most of the memory used by a C# process. The total memory is 10 GB, but the total reachable and unreachable objects altogether total 2.5 GB. I wonder what these 7.5 GB could be?
I'm looking for the most likely explanations or a method to find out what this memory can be.
Here is the precise situation. The process is .NET 4.5.1. It downloads pages from internet and process them with machine learning. The memory is almost entirely in the Managed Heap as shown by VMMap. This seems to rule out unmanaged memory leak.
The process has been running for days and the memory slowly grew. At some point, the memory is 11 GB. I stop everything running in the process. I run garbage collections including large object heap compaction several times (with one minute of interval):
GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce;
GC.Collect();
The memory goes down to 10 GB. Then I create the dump:
procdump -ma psid
The dump is 10 GB as expected.
I open the dump with .NET memory profiler (version 5.6). The dump shows a total of 2.2 GB reachable objects and 0.3 GB unreachable objects. What could explain the remaining 7.5 GB ?
Possible explanations I've been thinking of :
- the LOH does not really get fully compacted
- some memory is used beyond the objects displayed by the profiler
c# memory-profiling large-object-heap
c# memory-profiling large-object-heap
edited Nov 22 '18 at 11:34
Benoit Sanchez
asked Nov 17 '18 at 10:22
Benoit SanchezBenoit Sanchez
286113
286113
2
This is kind of equivalent to "got memory leak, plz fix.". What does your service do? Does it call into anything unmanaged? Does it use COM?
– fstam
Nov 17 '18 at 10:43
3
You should not have that many unreachable objects after a GC. A deadlocked finalizer thread causes memory explosions, use WinDbg to see what it is doing.
– Hans Passant
Nov 17 '18 at 10:44
Thanks Hans. This unreachable memory was indeed suspicious to me. I'll have a look.
– Benoit Sanchez
Nov 17 '18 at 11:35
1
Sounds like unmanaged memory usage. The JetBrains profiler can show that. You could also use the free VMMap.exe to test that theory.
– usr
Nov 17 '18 at 14:08
Thanks usr. I checked with VMMap. 95% of my 10 GB are in the managed heap. This seems to rule out unmanaged memory usage.
– Benoit Sanchez
Nov 17 '18 at 19:48
|
show 1 more comment
2
This is kind of equivalent to "got memory leak, plz fix.". What does your service do? Does it call into anything unmanaged? Does it use COM?
– fstam
Nov 17 '18 at 10:43
3
You should not have that many unreachable objects after a GC. A deadlocked finalizer thread causes memory explosions, use WinDbg to see what it is doing.
– Hans Passant
Nov 17 '18 at 10:44
Thanks Hans. This unreachable memory was indeed suspicious to me. I'll have a look.
– Benoit Sanchez
Nov 17 '18 at 11:35
1
Sounds like unmanaged memory usage. The JetBrains profiler can show that. You could also use the free VMMap.exe to test that theory.
– usr
Nov 17 '18 at 14:08
Thanks usr. I checked with VMMap. 95% of my 10 GB are in the managed heap. This seems to rule out unmanaged memory usage.
– Benoit Sanchez
Nov 17 '18 at 19:48
2
2
This is kind of equivalent to "got memory leak, plz fix.". What does your service do? Does it call into anything unmanaged? Does it use COM?
– fstam
Nov 17 '18 at 10:43
This is kind of equivalent to "got memory leak, plz fix.". What does your service do? Does it call into anything unmanaged? Does it use COM?
– fstam
Nov 17 '18 at 10:43
3
3
You should not have that many unreachable objects after a GC. A deadlocked finalizer thread causes memory explosions, use WinDbg to see what it is doing.
– Hans Passant
Nov 17 '18 at 10:44
You should not have that many unreachable objects after a GC. A deadlocked finalizer thread causes memory explosions, use WinDbg to see what it is doing.
– Hans Passant
Nov 17 '18 at 10:44
Thanks Hans. This unreachable memory was indeed suspicious to me. I'll have a look.
– Benoit Sanchez
Nov 17 '18 at 11:35
Thanks Hans. This unreachable memory was indeed suspicious to me. I'll have a look.
– Benoit Sanchez
Nov 17 '18 at 11:35
1
1
Sounds like unmanaged memory usage. The JetBrains profiler can show that. You could also use the free VMMap.exe to test that theory.
– usr
Nov 17 '18 at 14:08
Sounds like unmanaged memory usage. The JetBrains profiler can show that. You could also use the free VMMap.exe to test that theory.
– usr
Nov 17 '18 at 14:08
Thanks usr. I checked with VMMap. 95% of my 10 GB are in the managed heap. This seems to rule out unmanaged memory usage.
– Benoit Sanchez
Nov 17 '18 at 19:48
Thanks usr. I checked with VMMap. 95% of my 10 GB are in the managed heap. This seems to rule out unmanaged memory usage.
– Benoit Sanchez
Nov 17 '18 at 19:48
|
show 1 more comment
1 Answer
1
active
oldest
votes
After investigation, the problem happens to be heap fragmentation because of pinned buffers. I'll explain how to investigate and what pinned buffers are.
All profilers I've used agreed to say most of the heap is free. Now I needed to look at fragmentation. I can do it with WinDbg for example:
!dumpheap -stat
Then I looked at the "Fragmented blocks larger than..." section. WinDbg says objects lie between the free blocks making compaction impossible. Then I looked at what is holding these objects and if they are pinned, here for example object at address 0000000bfaf93b80:
!gcroot 0000000bfaf93b80
It displays the reference graph:
00000004082945e0 (async pinned handle)
-> 0000000535b3a3e0 System.Threading.OverlappedData
-> 00000006f5266d38 System.Threading.IOCompletionCallback
-> 0000000b35402220 System.Net.Sockets.SocketAsyncEventArgs
-> 0000000bf578c850 System.Net.Sockets.Socket
-> 0000000bf578c900 System.Net.SocketAddress
-> 0000000bfaf93b80 System.Byte
00000004082e2148 (pinned handle)
-> 0000000bfaf93b80 System.Byte
The last two lines tell you the object is pinned.
Pinned objects are buffers than can't be moved because their address is shared with non-managed code. Here you can guess it is the system TCP layer. When managed code needs to send the address of a buffer to external code, it needs to "pin" the buffer so that the address remains valid: the GC cannot move it.
These buffers, while being a very small part of the memory make compaction impossible and thus cause large memory "leak", even if it is not exactly a leak, more a fragmentation problem. This can happen on the LOH or on generational heaps just the same. Now the question is: what is causing these pinned objects to live forever: find the root cause of the leak that causes the fragmentation.
You can read similar questions here:
https://ayende.com/blog/181761-C/the-curse-of-memory-fragmentation
.NET deletes pinned allocated buffer (good explanation of pinned objects in the answer)
Note: the root cause was in a third party library AerospikeClient using the .NET async Socket API that is known for pinning the buffers sent to it. While AerospikeClient properly used a buffer pool, the buffer pool was re-created when re-creating their client. Since we re-created their client every hour instead of creating one forever, the buffer pool was re-created, causing a growing number of pinned buffers, in turn causing unlimited fragmentation. What remains unclear is why old buffers are never unpinned when transmission is over or at least when their client is disposed.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53350298%2flarge-unexplained-memory-in-the-memory-dump-of-a-net-process%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
After investigation, the problem happens to be heap fragmentation because of pinned buffers. I'll explain how to investigate and what pinned buffers are.
All profilers I've used agreed to say most of the heap is free. Now I needed to look at fragmentation. I can do it with WinDbg for example:
!dumpheap -stat
Then I looked at the "Fragmented blocks larger than..." section. WinDbg says objects lie between the free blocks making compaction impossible. Then I looked at what is holding these objects and if they are pinned, here for example object at address 0000000bfaf93b80:
!gcroot 0000000bfaf93b80
It displays the reference graph:
00000004082945e0 (async pinned handle)
-> 0000000535b3a3e0 System.Threading.OverlappedData
-> 00000006f5266d38 System.Threading.IOCompletionCallback
-> 0000000b35402220 System.Net.Sockets.SocketAsyncEventArgs
-> 0000000bf578c850 System.Net.Sockets.Socket
-> 0000000bf578c900 System.Net.SocketAddress
-> 0000000bfaf93b80 System.Byte
00000004082e2148 (pinned handle)
-> 0000000bfaf93b80 System.Byte
The last two lines tell you the object is pinned.
Pinned objects are buffers than can't be moved because their address is shared with non-managed code. Here you can guess it is the system TCP layer. When managed code needs to send the address of a buffer to external code, it needs to "pin" the buffer so that the address remains valid: the GC cannot move it.
These buffers, while being a very small part of the memory make compaction impossible and thus cause large memory "leak", even if it is not exactly a leak, more a fragmentation problem. This can happen on the LOH or on generational heaps just the same. Now the question is: what is causing these pinned objects to live forever: find the root cause of the leak that causes the fragmentation.
You can read similar questions here:
https://ayende.com/blog/181761-C/the-curse-of-memory-fragmentation
.NET deletes pinned allocated buffer (good explanation of pinned objects in the answer)
Note: the root cause was in a third party library AerospikeClient using the .NET async Socket API that is known for pinning the buffers sent to it. While AerospikeClient properly used a buffer pool, the buffer pool was re-created when re-creating their client. Since we re-created their client every hour instead of creating one forever, the buffer pool was re-created, causing a growing number of pinned buffers, in turn causing unlimited fragmentation. What remains unclear is why old buffers are never unpinned when transmission is over or at least when their client is disposed.
add a comment |
After investigation, the problem happens to be heap fragmentation because of pinned buffers. I'll explain how to investigate and what pinned buffers are.
All profilers I've used agreed to say most of the heap is free. Now I needed to look at fragmentation. I can do it with WinDbg for example:
!dumpheap -stat
Then I looked at the "Fragmented blocks larger than..." section. WinDbg says objects lie between the free blocks making compaction impossible. Then I looked at what is holding these objects and if they are pinned, here for example object at address 0000000bfaf93b80:
!gcroot 0000000bfaf93b80
It displays the reference graph:
00000004082945e0 (async pinned handle)
-> 0000000535b3a3e0 System.Threading.OverlappedData
-> 00000006f5266d38 System.Threading.IOCompletionCallback
-> 0000000b35402220 System.Net.Sockets.SocketAsyncEventArgs
-> 0000000bf578c850 System.Net.Sockets.Socket
-> 0000000bf578c900 System.Net.SocketAddress
-> 0000000bfaf93b80 System.Byte
00000004082e2148 (pinned handle)
-> 0000000bfaf93b80 System.Byte
The last two lines tell you the object is pinned.
Pinned objects are buffers than can't be moved because their address is shared with non-managed code. Here you can guess it is the system TCP layer. When managed code needs to send the address of a buffer to external code, it needs to "pin" the buffer so that the address remains valid: the GC cannot move it.
These buffers, while being a very small part of the memory make compaction impossible and thus cause large memory "leak", even if it is not exactly a leak, more a fragmentation problem. This can happen on the LOH or on generational heaps just the same. Now the question is: what is causing these pinned objects to live forever: find the root cause of the leak that causes the fragmentation.
You can read similar questions here:
https://ayende.com/blog/181761-C/the-curse-of-memory-fragmentation
.NET deletes pinned allocated buffer (good explanation of pinned objects in the answer)
Note: the root cause was in a third party library AerospikeClient using the .NET async Socket API that is known for pinning the buffers sent to it. While AerospikeClient properly used a buffer pool, the buffer pool was re-created when re-creating their client. Since we re-created their client every hour instead of creating one forever, the buffer pool was re-created, causing a growing number of pinned buffers, in turn causing unlimited fragmentation. What remains unclear is why old buffers are never unpinned when transmission is over or at least when their client is disposed.
add a comment |
After investigation, the problem happens to be heap fragmentation because of pinned buffers. I'll explain how to investigate and what pinned buffers are.
All profilers I've used agreed to say most of the heap is free. Now I needed to look at fragmentation. I can do it with WinDbg for example:
!dumpheap -stat
Then I looked at the "Fragmented blocks larger than..." section. WinDbg says objects lie between the free blocks making compaction impossible. Then I looked at what is holding these objects and if they are pinned, here for example object at address 0000000bfaf93b80:
!gcroot 0000000bfaf93b80
It displays the reference graph:
00000004082945e0 (async pinned handle)
-> 0000000535b3a3e0 System.Threading.OverlappedData
-> 00000006f5266d38 System.Threading.IOCompletionCallback
-> 0000000b35402220 System.Net.Sockets.SocketAsyncEventArgs
-> 0000000bf578c850 System.Net.Sockets.Socket
-> 0000000bf578c900 System.Net.SocketAddress
-> 0000000bfaf93b80 System.Byte
00000004082e2148 (pinned handle)
-> 0000000bfaf93b80 System.Byte
The last two lines tell you the object is pinned.
Pinned objects are buffers than can't be moved because their address is shared with non-managed code. Here you can guess it is the system TCP layer. When managed code needs to send the address of a buffer to external code, it needs to "pin" the buffer so that the address remains valid: the GC cannot move it.
These buffers, while being a very small part of the memory make compaction impossible and thus cause large memory "leak", even if it is not exactly a leak, more a fragmentation problem. This can happen on the LOH or on generational heaps just the same. Now the question is: what is causing these pinned objects to live forever: find the root cause of the leak that causes the fragmentation.
You can read similar questions here:
https://ayende.com/blog/181761-C/the-curse-of-memory-fragmentation
.NET deletes pinned allocated buffer (good explanation of pinned objects in the answer)
Note: the root cause was in a third party library AerospikeClient using the .NET async Socket API that is known for pinning the buffers sent to it. While AerospikeClient properly used a buffer pool, the buffer pool was re-created when re-creating their client. Since we re-created their client every hour instead of creating one forever, the buffer pool was re-created, causing a growing number of pinned buffers, in turn causing unlimited fragmentation. What remains unclear is why old buffers are never unpinned when transmission is over or at least when their client is disposed.
After investigation, the problem happens to be heap fragmentation because of pinned buffers. I'll explain how to investigate and what pinned buffers are.
All profilers I've used agreed to say most of the heap is free. Now I needed to look at fragmentation. I can do it with WinDbg for example:
!dumpheap -stat
Then I looked at the "Fragmented blocks larger than..." section. WinDbg says objects lie between the free blocks making compaction impossible. Then I looked at what is holding these objects and if they are pinned, here for example object at address 0000000bfaf93b80:
!gcroot 0000000bfaf93b80
It displays the reference graph:
00000004082945e0 (async pinned handle)
-> 0000000535b3a3e0 System.Threading.OverlappedData
-> 00000006f5266d38 System.Threading.IOCompletionCallback
-> 0000000b35402220 System.Net.Sockets.SocketAsyncEventArgs
-> 0000000bf578c850 System.Net.Sockets.Socket
-> 0000000bf578c900 System.Net.SocketAddress
-> 0000000bfaf93b80 System.Byte
00000004082e2148 (pinned handle)
-> 0000000bfaf93b80 System.Byte
The last two lines tell you the object is pinned.
Pinned objects are buffers than can't be moved because their address is shared with non-managed code. Here you can guess it is the system TCP layer. When managed code needs to send the address of a buffer to external code, it needs to "pin" the buffer so that the address remains valid: the GC cannot move it.
These buffers, while being a very small part of the memory make compaction impossible and thus cause large memory "leak", even if it is not exactly a leak, more a fragmentation problem. This can happen on the LOH or on generational heaps just the same. Now the question is: what is causing these pinned objects to live forever: find the root cause of the leak that causes the fragmentation.
You can read similar questions here:
https://ayende.com/blog/181761-C/the-curse-of-memory-fragmentation
.NET deletes pinned allocated buffer (good explanation of pinned objects in the answer)
Note: the root cause was in a third party library AerospikeClient using the .NET async Socket API that is known for pinning the buffers sent to it. While AerospikeClient properly used a buffer pool, the buffer pool was re-created when re-creating their client. Since we re-created their client every hour instead of creating one forever, the buffer pool was re-created, causing a growing number of pinned buffers, in turn causing unlimited fragmentation. What remains unclear is why old buffers are never unpinned when transmission is over or at least when their client is disposed.
edited Nov 22 '18 at 11:38
answered Nov 19 '18 at 13:05
Benoit SanchezBenoit Sanchez
286113
286113
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53350298%2flarge-unexplained-memory-in-the-memory-dump-of-a-net-process%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
2
This is kind of equivalent to "got memory leak, plz fix.". What does your service do? Does it call into anything unmanaged? Does it use COM?
– fstam
Nov 17 '18 at 10:43
3
You should not have that many unreachable objects after a GC. A deadlocked finalizer thread causes memory explosions, use WinDbg to see what it is doing.
– Hans Passant
Nov 17 '18 at 10:44
Thanks Hans. This unreachable memory was indeed suspicious to me. I'll have a look.
– Benoit Sanchez
Nov 17 '18 at 11:35
1
Sounds like unmanaged memory usage. The JetBrains profiler can show that. You could also use the free VMMap.exe to test that theory.
– usr
Nov 17 '18 at 14:08
Thanks usr. I checked with VMMap. 95% of my 10 GB are in the managed heap. This seems to rule out unmanaged memory usage.
– Benoit Sanchez
Nov 17 '18 at 19:48