@@ -220,11 +220,17 @@ AffinitySet g_processAffinitySet;
220220extern " C" int g_highestNumaNode;
221221extern " C" bool g_numaAvailable;
222222
223+ #ifdef TARGET_APPLE
224+ static int *g_kern_memorystatus_level_mib = NULL ;
225+ static size_t g_kern_memorystatus_level_mib_length = 0 ;
226+ #endif
227+
223228// Initialize the interface implementation
224229// Return:
225230// true if it has succeeded, false if it has failed
226231bool GCToOSInterface::Initialize ()
227232{
233+ bool success = true ;
228234 int pageSize = sysconf ( _SC_PAGE_SIZE );
229235
230236 g_pageSizeUnixInl = uint32_t ((pageSize > 0 ) ? pageSize : 0x1000 );
@@ -317,7 +323,24 @@ bool GCToOSInterface::Initialize()
317323
318324 NUMASupportInitialize ();
319325
320- return true ;
326+ #ifdef TARGET_APPLE
327+ const char * mem_free_name = " kern.memorystatus_level" ;
328+ int rc = sysctlnametomib (mem_free_name, NULL , &g_kern_memorystatus_level_mib_length);
329+ if (rc == 0 )
330+ {
331+ g_kern_memorystatus_level_mib = (int *)malloc (g_kern_memorystatus_level_mib_length * sizeof (int ));
332+ rc = sysctlnametomib (mem_free_name, g_kern_memorystatus_level_mib, &g_kern_memorystatus_level_mib_length);
333+ if (rc != 0 )
334+ {
335+ free (g_kern_memorystatus_level_mib);
336+ g_kern_memorystatus_level_mib = NULL ;
337+ g_kern_memorystatus_level_mib_length = 0 ;
338+ success = false ;
339+ }
340+ }
341+ #endif
342+
343+ return success;
321344}
322345
323346// Shutdown the interface implementation
@@ -1248,20 +1271,23 @@ uint64_t GetAvailablePhysicalMemory()
12481271
12491272 // Get the physical memory available.
12501273#if defined(__APPLE__)
1251- vm_size_t page_size;
1252- mach_port_t mach_port;
1253- mach_msg_type_number_t count;
1254- vm_statistics_data_t vm_stats;
1255- mach_port = mach_host_self ();
1256- count = sizeof (vm_stats) / sizeof (natural_t );
1257- if (KERN_SUCCESS == host_page_size (mach_port, &page_size))
1274+ uint32_t mem_free = 0 ;
1275+ size_t mem_free_length = sizeof (uint32_t );
1276+ if (g_kern_memorystatus_level_mib != NULL )
12581277 {
1259- if (KERN_SUCCESS == host_statistics (mach_port, HOST_VM_INFO, (host_info_t )&vm_stats, &count))
1278+ int rc = sysctl (g_kern_memorystatus_level_mib, g_kern_memorystatus_level_mib_length, &mem_free, &mem_free_length, NULL , 0 );
1279+ if (rc == 0 )
12601280 {
1261- available = (int64_t )vm_stats.free_count * (int64_t )page_size;
1281+ int64_t mem_size = 0 ;
1282+ size_t mem_size_length = sizeof (int64_t );
1283+ int mib[] = { CTL_HW, HW_MEMSIZE };
1284+ rc = sysctl (mib, 2 , &mem_size, &mem_size_length, NULL , 0 );
1285+ if (rc == 0 )
1286+ {
1287+ available = (int64_t )mem_free * mem_size / 100 ;
1288+ }
12621289 }
12631290 }
1264- mach_port_deallocate (mach_task_self (), mach_port);
12651291#elif defined(__FreeBSD__)
12661292 size_t inactive_count = 0 , laundry_count = 0 , free_count = 0 ;
12671293 size_t sz = sizeof (inactive_count);
@@ -1279,7 +1305,7 @@ uint64_t GetAvailablePhysicalMemory()
12791305
12801306 if (tryReadMemInfo)
12811307 {
1282- // Ensure that we don't try to read the /proc/meminfo in successive calls to the GlobalMemoryStatusEx
1308+ // Ensure that we don't try to read the /proc/meminfo in successive calls to the GetAvailablePhysicalMemory
12831309 // if we have failed to access the file or the file didn't contain the MemAvailable value.
12841310 tryReadMemInfo = ReadMemAvailable (&available);
12851311 }
0 commit comments