Skip to content

Commit c07a81f

Browse files
authored
[NativeAOT] collect garbage when memory is low (#103857)
This matches the existing feature in CoreCLR: https://github.com/dotnet/runtime/blob/main/src/coreclr/vm/finalizerthread.cpp#L250
1 parent 7294674 commit c07a81f

File tree

5 files changed

+18
-8
lines changed

5 files changed

+18
-8
lines changed

src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/__Finalizer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public static void ProcessFinalizers()
3939
{
4040
// RhpWaitForFinalizerRequest() returned false and indicated that memory is low. We help
4141
// out by initiating a garbage collection and then go back to waiting for another request.
42-
InternalCalls.RhCollect(-1, InternalGCCollectionMode.Blocking);
42+
InternalCalls.RhCollect(0, InternalGCCollectionMode.Blocking, lowMemoryP: true);
4343
}
4444
}
4545
}

src/coreclr/nativeaot/Runtime/FinalizerHelpers.cpp

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ GPTR_DECL(Thread, g_pFinalizerThread);
2727
CLREventStatic g_FinalizerEvent;
2828
CLREventStatic g_FinalizerDoneEvent;
2929

30+
static HANDLE g_lowMemoryNotification = NULL;
31+
3032
EXTERN_C void QCALLTYPE ProcessFinalizers();
3133

3234
// Unmanaged front-end to the finalizer thread. We require this because at the point the GC creates the
@@ -76,6 +78,7 @@ bool RhInitializeFinalization()
7678
return false;
7779
if (!g_FinalizerDoneEvent.CreateManualEventNoThrow(false))
7880
return false;
81+
g_lowMemoryNotification = PalCreateLowMemoryResourceNotification();
7982

8083
// Create the finalizer thread itself.
8184
if (!PalStartFinalizerThread(FinalizerStart, (void*)g_FinalizerEvent.GetOSEvent()))
@@ -132,17 +135,12 @@ EXTERN_C UInt32_BOOL QCALLTYPE RhpWaitForFinalizerRequest()
132135
// two second timeout expires.
133136
do
134137
{
135-
HANDLE lowMemEvent = NULL;
136-
#if 0 // TODO: hook up low memory notification
137-
lowMemEvent = pHeap->GetLowMemoryNotificationEvent();
138+
HANDLE lowMemEvent = g_lowMemoryNotification;
138139
HANDLE rgWaitHandles[] = { g_FinalizerEvent.GetOSEvent(), lowMemEvent };
139140
uint32_t cWaitHandles = (fLastEventWasLowMemory || (lowMemEvent == NULL)) ? 1 : 2;
140141
uint32_t uTimeout = fLastEventWasLowMemory ? 2000 : INFINITE;
141142

142-
uint32_t uResult = PalWaitForMultipleObjectsEx(cWaitHandles, rgWaitHandles, FALSE, uTimeout, FALSE);
143-
#else
144-
uint32_t uResult = PalWaitForSingleObjectEx(g_FinalizerEvent.GetOSEvent(), INFINITE, FALSE);
145-
#endif
143+
uint32_t uResult = PalCompatibleWaitAny(/*alertable=*/ FALSE, uTimeout, cWaitHandles, rgWaitHandles, /*allowReentrantWait=*/ FALSE);
146144

147145
switch (uResult)
148146
{

src/coreclr/nativeaot/Runtime/PalRedhawk.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -706,6 +706,8 @@ REDHAWK_PALIMPORT UInt32_BOOL REDHAWK_PALAPI PalMarkThunksAsValidCallTargets(
706706

707707
REDHAWK_PALIMPORT uint32_t REDHAWK_PALAPI PalCompatibleWaitAny(UInt32_BOOL alertable, uint32_t timeout, uint32_t count, HANDLE* pHandles, UInt32_BOOL allowReentrantWait);
708708

709+
REDHAWK_PALIMPORT HANDLE PalCreateLowMemoryResourceNotification();
710+
709711
REDHAWK_PALIMPORT void REDHAWK_PALAPI PalAttachThread(void* thread);
710712
REDHAWK_PALIMPORT bool REDHAWK_PALAPI PalDetachThread(void* thread);
711713

src/coreclr/nativeaot/Runtime/unix/PalRedhawkUnix.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1126,6 +1126,11 @@ REDHAWK_PALEXPORT uint32_t REDHAWK_PALAPI PalCompatibleWaitAny(UInt32_BOOL alert
11261126
return WaitForSingleObjectEx(pHandles[0], timeout, alertable);
11271127
}
11281128

1129+
REDHAWK_PALEXPORT HANDLE PalCreateLowMemoryResourceNotification()
1130+
{
1131+
return NULL;
1132+
}
1133+
11291134
#if !__has_builtin(_mm_pause)
11301135
extern "C" void _mm_pause()
11311136
// Defined for implementing PalYieldProcessor in PalRedhawk.h

src/coreclr/nativeaot/Runtime/windows/PalRedhawkMinWin.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,11 @@ REDHAWK_PALEXPORT uint32_t REDHAWK_PALAPI PalCompatibleWaitAny(UInt32_BOOL alert
312312
}
313313
}
314314

315+
REDHAWK_PALEXPORT HANDLE PalCreateLowMemoryResourceNotification()
316+
{
317+
return CreateMemoryResourceNotification(LowMemoryResourceNotification);
318+
}
319+
315320
REDHAWK_PALEXPORT void REDHAWK_PALAPI PalSleep(uint32_t milliseconds)
316321
{
317322
return Sleep(milliseconds);

0 commit comments

Comments
 (0)