question

BobBryan-5041 avatar image
0 Votes"
BobBryan-5041 asked BobBryan-5041 answered

When allocating with the new keyword, does the CLR ever throttle via a Sleep statement when memory is low

I came across this answer on Stack Overflow:

When you allocate faster than you can garbage collect you will run into OOM. If you do heavy allocations the CLR will insert a Sleep(xx) to throttle allocation but this is not enough in your extreme case.

So, I have not read anything about the CLR throttling allocations by inserting a Sleep statement to slow down allocations when memory is low. Can you confirm if this is true or not? If it is true, then Is there any documentation that talks about the details. I have tried doing Google searches, but could not find anything to support this claim.



dotnet-csharp
· 6
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

.NET Core CLR is open sourced, so if you want to see what exactly is there, the code is your one and only guide, https://github.com/dotnet/runtime . What you would explore is around GC, https://github.com/dotnet/runtime/blob/main/docs/design/coreclr/botr/garbage-collection.md

0 Votes 0 ·

Unsure what the basis for this question other than you have a memory leak or are simply curious. In either case if a developer needs to circumvent the GC than this is merely a work-a-round to the real issue at hand. Consider using performance profiler in Visual Studio or a tool like jetbrains dotmemory.

Once the problem has been identified and is not from say a C++ import refactor the code and if unsure how ask here.

If from an imported DLL then hopefully there is support that can assist you.



0 Votes 0 ·

If you really must know the underlying reason I'm asking the question - it is because I'm looking into writing a custom Array Pooling class and would like to provide an option to either slow down allocations or prune (trim) previously allocated arrays that have not been used for a while, or both. The user of the class would decide if either of these should be used. If the CLR already inserts a sleep statement when memory is low, then I think it is pretty obvious that my class should not do the same.

It does not sound like either you or @lextm has any idea if the question I asked is true or not. So, would it be too much to ask that you ask someone that works on the GC team (and is familiar with allocations with the new operator) and ask them if they have ever heard of this before. I'm quite willing to accept their word for it. Or is this forbidden?

I am also looking at how to detect high memory usage situations from C#. For example, I have tried this test:

 int[] buf1 = new int[134217728]; // Allocates .5 gb.

I have tried various memory profiling tools like Perfmon, Resource Monitor, Task Manager, etc. but they all show that available memory is unaffected by C# heap allocations. If you are skeptical, then try using the memory profiling tool of your choice and see if allocations like this affects affects free memory. On my Windows 10 pro machine, it does not.

So, that leads me to ask - does the garbage collector use a different definition of "free memory" that includes heap allocations, and if so, how can I get that value from my C# .NET 6 app?

0 Votes 0 ·

A little more background on what I tried to obtain available memory. I tried using the following GC method:

 long totMem = GC.GetTotalMemory(false);

But, this returned 88,552 on my machine, so it looks like this is for process memory. After allocating .5 GB, it read 536,959,520.

I also tried to use the GC.GetGCMemoryInfo method. I was initially quite hopeful that the TotalAvailableMemoryBytes value would return the amount of free memory. But, instead it returned a value of 16,976,510,976, which is just under the 16 GB (17,179,869,184 bytes) installed on my test system. Also, this value did not change after I allocated .5 GB. So, I'm not quite sure what this value is supposed to represent.

I also tried implementing a PerformanceInfo class as given in this link on Stack Overflow: https://stackoverflow.com/a/10028263/643828
The PhysicalAvailable field returns the same available memory as in the other memory profiling tools like Task Manager.

0 Votes 0 ·

@BobBryan-5041
We usually discuss the specific problems encountered in the programming process in the c# forum, but according to your description, your problem is a more in-depth mechanism problem.
For these issues, I think it might be more appropriate to raise them in the GitHub repository mentioned by lextm.

0 Votes 0 ·

You posted your own answer on Stack Overflow, https://stackoverflow.com/questions/68960474/when-allocating-with-the-new-keyword-does-the-clr-ever-throttle-via-a-sleep-sta so probably you should do the same here.

0 Votes 0 ·

1 Answer

BobBryan-5041 avatar image
0 Votes"
BobBryan-5041 answered

From my answer on Stack Overflow:

In conclusion, the answer to the question I posed is yes, the CLR does throttle allocations when a background GC is running. The rationale to throttling allocations appears to be to allow the background GC to complete its job more quickly and efficiently.


5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.