Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Low memory handling? #6919

Open
mogmios opened this issue Nov 1, 2016 · 15 comments
Open

Low memory handling? #6919

mogmios opened this issue Nov 1, 2016 · 15 comments
Labels
area-GC-coreclr design-discussion Ongoing discussion about design without consensus
Milestone

Comments

@mogmios
Copy link

mogmios commented Nov 1, 2016

In CLR / .NET / C# is there any standard cross-platform way to receive a low memory notice before actually running out of memory? With Xamarin you can use DidReceiveMemoryWarning and there seems to be a couple methods specific to Windows that don't seem to work even on Windows.

MemoryManager AppMemoryUsageDecreased and most of the related functionality will compile ok but then throw mystery errors at runtime that don't seem to make any sense or be explained by Googling. Happened when registering any of the events and with most method calls.

I thought there might be some sort of event I could listen for but I'm not finding one. Simply marking fields with some sort of LowMemoryAction attribute seemed a possibility also but didn't find anything like that either.

For example, I have an object that computes an expensive operation for a FileSystemInfo object and which will run recursively to children if it represents a directory. I cache the result of the operation to speed up repeated calls but the operation can be redone without problem if need be. I'd like to be able to clear this cache if memory gets low. Currently using MemoryCache but it's not a very good solution.

@Maoni0
Copy link
Member

Maoni0 commented Nov 7, 2016

We don't provide anything like this from the GC. As you noticed, there are things from other higher level components that chose to provide such notifications themselves which may or may not work for you.

I am not aware of any xplat ways. You could of course detect memory load on the machine yourself (on Windows this is via GlobalMemoryStatusEx which is what GC uses).

@ayende
Copy link
Contributor

ayende commented Nov 10, 2016

Note that in Linux, for example, there is no way for the system to warn you that it is running out of memory.
Instead, it will start swapping and then killing processes to free memory

@ayende
Copy link
Contributor

ayende commented Nov 10, 2016

Pretty much the only way we found to do that on Linux was to poll for memory status and raise our own events.

@gkhanna79
Copy link
Member

Is there anything actionable here?

@Maoni0
Copy link
Member

Maoni0 commented Mar 5, 2017

nothing actionable from the GC side.

@gkhanna79
Copy link
Member

Should the issue be closed in that case?

@davidfowl
Copy link
Member

I think it's worth investigating what this event would look like from a cross platform POV. We recently had some design meetings about the ASP.NET cache where we decided to separate the detection of memory pressure from the cache itself. A cross platform component that can detect "low memory" would be super valuable for many scenarios. Do we know if other languages/platfprms/runtimes offer anything here?

@ayende what did you end up doing? Did you make it a library?

@ayende
Copy link
Contributor

ayende commented Mar 6, 2017

@davidfowl I'm polling: https://github.com/ravendb/ravendb/blob/v4.0/src/Raven.Server/ServerWide/LowMemoryNotification/PosixLowMemoryNotification.cs#L29

Note that I absolutely agree that a generic component will be useful here.
Note that it also need to handle such things as containers' limited memory / jobs limited memory.

@Maoni0
Copy link
Member

Maoni0 commented Mar 6, 2017

on a related note, with hosting APIs (which unfortunately only exist on desktop) you can implement a pattern that says "as a host I decide that this is a low memory situation, so I will do all the clean up type of things (in the cache case it might mean to expire a bunch of cached entries), then I will inform the GC it should consider it a low memory situation", this helps the subsequent GC to reclaim more memory.

@davidfowl
Copy link
Member

/cc @KKhurin

@ayende
Copy link
Contributor

ayende commented Mar 6, 2017

@Maoni0 Yes, if we can be notified by the host that we are running out of memory, or that a big GC is about to happen, we can do quite a lot to make it more efficient (removed pinned memory, for example), clear caches, etc.

@gkhanna79
Copy link
Member

@Maoni0 Are you suggesting that folks needing this notification write their own, instead of using the .NEt Core Host?

IMHO, .NET Core host should not participate in Runtime's policy of memory management or notification and this infrastructure is something that should be built into the runtime, enabling any future hosts to be able to take advantage of it.

@Maoni0
Copy link
Member

Maoni0 commented Mar 6, 2017

to be clear, it's not the host infrastructure that would participate in deciding what low memory looks like. it's the host that implements the hosting interface that decides when it wants the runtime to consider it's low memory. with hosting API you would register a ICLRMemoryNotificationCallback* with the IHostMemoryManager::RegisterMemoryNotificationCallback method. and the host would indicate if it wants the CLR to think it's low, normal or high on memory by implementing ICLRMemoryNotificationCallback::OnMemoryNotification. so when ICLRMemoryNotificationCallback::OnMemoryNotification says it's eMemoryAvailableLow, the finalizer thread will trigger a GC right away and GC will recognize this as "we are in low memory situation and should be more aggressive about doing GCs". additionally, the host can also implement IHostMemoryManager::GetMemoryLoad Method which tells GC what the percentage of memory load it wants the GC to think is.

I imagine this was how SQL used it (as most of these hosting interfaces were made for them). that was before my time. I am certainly open to revamping these interfaces if the current ones aren't sufficient/user friendly enough. of course to revamp hosting interfaces it would need collaboration from folks who own hosting.

@msftgits msftgits transferred this issue from dotnet/coreclr Jan 31, 2020
@msftgits msftgits added this to the Future milestone Jan 31, 2020
@mangod9
Copy link
Member

mangod9 commented Sep 22, 2020

would something like this #6051 satisfy this requirement?

@timcassell
Copy link

If/when this makes it into the runtime, would it then make sense to add a SoftReference<T> type? Similar to WeakReference<T>, but only collects on low memory instead of any GC. This would be useful for an unlimited-timeout memory cache (as opposed to MemoryCache).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-GC-coreclr design-discussion Ongoing discussion about design without consensus
Projects
None yet
Development

No branches or pull requests

9 participants