public static unsafe MemoryInfoResult GetMemoryInfo() { if (_failedToGetAvailablePhysicalMemory) { if (Logger.IsInfoEnabled) { Logger.Info("Because of a previous error in getting available memory, we are now lying and saying we have 256MB free"); } return(FailedResult); } try { if (PlatformDetails.RunningOnPosix == false) { // Windows var memoryStatus = new MemoryStatusEx { dwLength = (uint)sizeof(MemoryStatusEx) }; var result = GlobalMemoryStatusEx(&memoryStatus); if (result == false) { if (Logger.IsInfoEnabled) { Logger.Info("Failure when trying to read memory info from Windows, error code is: " + Marshal.GetLastWin32Error()); } return(FailedResult); } return(new MemoryInfoResult { AvailableMemory = new Size((long)memoryStatus.ullAvailPhys, SizeUnit.Bytes), TotalPhysicalMemory = new Size((long)memoryStatus.ullTotalPhys, SizeUnit.Bytes), }); } // read both cgroup and sysinfo memory stats, and use the lowest if applicable var cgroupMemoryLimit = KernelVirtualFileSystemUtils.ReadNumberFromCgroupFile("/sys/fs/cgroup/memory/memory.limit_in_bytes"); var cgroupMemoryUsage = KernelVirtualFileSystemUtils.ReadNumberFromCgroupFile("/sys/fs/cgroup/memory/memory.usage_in_bytes"); ulong availableRamInBytes; ulong totalPhysicalMemoryInBytes; if (PlatformDetails.RunningOnMacOsx == false) { // Linux var info = new sysinfo_t(); if (Syscall.sysinfo(ref info) != 0) { if (Logger.IsInfoEnabled) { Logger.Info("Failure when trying to read memory info from posix, error code was: " + Marshal.GetLastWin32Error()); } return(FailedResult); } availableRamInBytes = info.AvailableRam; totalPhysicalMemoryInBytes = info.TotalRam; } else { // MacOS var mib = new[] { (int)TopLevelIdentifiersMacOs.CTL_HW, (int)CtkHwIdentifiersMacOs.HW_MEMSIZE }; ulong physicalMemory = 0; var len = sizeof(ulong); if (Syscall.sysctl(mib, 2, &physicalMemory, &len, null, UIntPtr.Zero) != 0) { if (Logger.IsInfoEnabled) { Logger.Info("Failure when trying to read physical memory info from MacOS, error code was: " + Marshal.GetLastWin32Error()); } return(FailedResult); } totalPhysicalMemoryInBytes = physicalMemory; uint pageSize; var vmStats = new vm_statistics64(); var machPort = Syscall.mach_host_self(); var count = sizeof(vm_statistics64) / sizeof(uint); if (Syscall.host_page_size(machPort, &pageSize) != 0 || Syscall.host_statistics64(machPort, (int)FlavorMacOs.HOST_VM_INFO64, &vmStats, &count) != 0) { if (Logger.IsInfoEnabled) { Logger.Info("Failure when trying to get vm_stats from MacOS, error code was: " + Marshal.GetLastWin32Error()); } return(FailedResult); } availableRamInBytes = vmStats.FreePagesCount * (ulong)pageSize; } Size availableRam, totalPhysicalMemory; if (cgroupMemoryLimit < (long)totalPhysicalMemoryInBytes) { availableRam = new Size(cgroupMemoryLimit - cgroupMemoryUsage, SizeUnit.Bytes); totalPhysicalMemory = new Size(cgroupMemoryLimit, SizeUnit.Bytes); } else { availableRam = new Size((long)availableRamInBytes, SizeUnit.Bytes); totalPhysicalMemory = new Size((long)totalPhysicalMemoryInBytes, SizeUnit.Bytes); } return(new MemoryInfoResult { AvailableMemory = availableRam, TotalPhysicalMemory = totalPhysicalMemory }); } catch (Exception e) { if (Logger.IsInfoEnabled) { Logger.Info("Error while trying to get available memory, will stop trying and report that there is 256MB free only from now on", e); } _failedToGetAvailablePhysicalMemory = true; return(FailedResult); } }
public static unsafe MemoryInfoResult GetMemoryInfo() { if (_failedToGetAvailablePhysicalMemory) { if (Logger.IsInfoEnabled) { Logger.Info("Because of a previous error in getting available memory, we are now lying and saying we have 256MB free"); } return(FailedResult); } try { if (PlatformDetails.RunningOnPosix == false) { // windows var memoryStatus = new MemoryStatusEx { dwLength = (uint)sizeof(MemoryStatusEx) }; if (GlobalMemoryStatusEx(&memoryStatus) == false) { if (Logger.IsInfoEnabled) { Logger.Info("Failure when trying to read memory info from Windows, error code is: " + Marshal.GetLastWin32Error()); } return(FailedResult); } // The amount of physical memory retrieved by the GetPhysicallyInstalledSystemMemory function // must be equal to or greater than the amount reported by the GlobalMemoryStatusEx function // if it is less, the SMBIOS data is malformed and the function fails with ERROR_INVALID_DATA. // Malformed SMBIOS data may indicate a problem with the user's computer. var fetchedInstalledMemory = GetPhysicallyInstalledSystemMemory(out var installedMemoryInKb); SetMemoryRecords((long)memoryStatus.ullAvailPhys); return(new MemoryInfoResult { TotalCommittableMemory = new Size((long)memoryStatus.ullTotalPageFile, SizeUnit.Bytes), CurrentCommitCharge = new Size((long)(memoryStatus.ullTotalPageFile - memoryStatus.ullAvailPageFile), SizeUnit.Bytes), AvailableMemory = new Size((long)memoryStatus.ullAvailPhys, SizeUnit.Bytes), TotalPhysicalMemory = new Size((long)memoryStatus.ullTotalPhys, SizeUnit.Bytes), InstalledMemory = fetchedInstalledMemory ? new Size(installedMemoryInKb, SizeUnit.Kilobytes) : new Size((long)memoryStatus.ullTotalPhys, SizeUnit.Bytes), MemoryUsageRecords = new MemoryInfoResult.MemoryUsageLowHigh { High = new MemoryInfoResult.MemoryUsageIntervals { LastOneMinute = new Size(HighLastOneMinute, SizeUnit.Bytes), LastFiveMinutes = new Size(HighLastFiveMinutes, SizeUnit.Bytes), SinceStartup = new Size(HighSinceStartup, SizeUnit.Bytes) }, Low = new MemoryInfoResult.MemoryUsageIntervals { LastOneMinute = new Size(LowLastOneMinute, SizeUnit.Bytes), LastFiveMinutes = new Size(LowLastFiveMinutes, SizeUnit.Bytes), SinceStartup = new Size(LowSinceStartup, SizeUnit.Bytes) } } }); } // read both cgroup and sysinfo memory stats, and use the lowest if applicable var cgroupMemoryLimit = KernelVirtualFileSystemUtils.ReadNumberFromCgroupFile("/sys/fs/cgroup/memory/memory.limit_in_bytes"); var cgroupMemoryUsage = KernelVirtualFileSystemUtils.ReadNumberFromCgroupFile("/sys/fs/cgroup/memory/memory.usage_in_bytes"); ulong availableRamInBytes; ulong totalPhysicalMemoryInBytes; if (PlatformDetails.RunningOnMacOsx == false) { // linux int rc = 0; ulong totalram = 0; if (PlatformDetails.Is32Bits == false) { var info = new sysinfo_t(); rc = Syscall.sysinfo(ref info); totalram = info.TotalRam; } else { var info = new sysinfo_t_32bit(); rc = Syscall.sysinfo(ref info); totalram = info.TotalRam; } if (rc != 0) { if (Logger.IsInfoEnabled) { Logger.Info("Failure when trying to read memory info from posix, error code was: " + Marshal.GetLastWin32Error()); } return(FailedResult); } var availableAndFree = GetAvailableAndFreeMemoryFromProcMemInfo(); availableRamInBytes = (ulong)availableAndFree.MemAvailable; totalPhysicalMemoryInBytes = totalram; } else { // macOS var mib = new[] { (int)TopLevelIdentifiersMacOs.CTL_HW, (int)CtkHwIdentifiersMacOs.HW_MEMSIZE }; ulong physicalMemory = 0; var len = sizeof(ulong); if (Syscall.sysctl(mib, 2, &physicalMemory, &len, null, UIntPtr.Zero) != 0) { if (Logger.IsInfoEnabled) { Logger.Info("Failure when trying to read physical memory info from MacOS, error code was: " + Marshal.GetLastWin32Error()); } return(FailedResult); } totalPhysicalMemoryInBytes = physicalMemory; uint pageSize; var vmStats = new vm_statistics64(); var machPort = Syscall.mach_host_self(); var count = sizeof(vm_statistics64) / sizeof(uint); if (Syscall.host_page_size(machPort, &pageSize) != 0 || Syscall.host_statistics64(machPort, (int)FlavorMacOs.HOST_VM_INFO64, &vmStats, &count) != 0) { if (Logger.IsInfoEnabled) { Logger.Info("Failure when trying to get vm_stats from MacOS, error code was: " + Marshal.GetLastWin32Error()); } return(FailedResult); } availableRamInBytes = (vmStats.FreePagesCount + vmStats.InactivePagesCount) * (ulong)pageSize; } Size availableRam, totalPhysicalMemory; if (cgroupMemoryLimit < (long)totalPhysicalMemoryInBytes) { availableRam = new Size(cgroupMemoryLimit - cgroupMemoryUsage, SizeUnit.Bytes); totalPhysicalMemory = new Size(cgroupMemoryLimit, SizeUnit.Bytes); } else { availableRam = new Size((long)availableRamInBytes, SizeUnit.Bytes); totalPhysicalMemory = new Size((long)totalPhysicalMemoryInBytes, SizeUnit.Bytes); } SetMemoryRecords((long)availableRamInBytes); var commitAsAndCommitLimit = GetCommitAsAndCommitLimitFromProcMemInfo(); return(new MemoryInfoResult { TotalCommittableMemory = new Size(commitAsAndCommitLimit.CommitLimit, SizeUnit.Kilobytes), CurrentCommitCharge = new Size(commitAsAndCommitLimit.Committed_AS, SizeUnit.Kilobytes), AvailableMemory = availableRam, TotalPhysicalMemory = totalPhysicalMemory, InstalledMemory = totalPhysicalMemory, MemoryUsageRecords = new MemoryInfoResult.MemoryUsageLowHigh { High = new MemoryInfoResult.MemoryUsageIntervals { LastOneMinute = new Size(HighLastOneMinute, SizeUnit.Bytes), LastFiveMinutes = new Size(HighLastFiveMinutes, SizeUnit.Bytes), SinceStartup = new Size(HighSinceStartup, SizeUnit.Bytes) }, Low = new MemoryInfoResult.MemoryUsageIntervals { LastOneMinute = new Size(LowLastOneMinute, SizeUnit.Bytes), LastFiveMinutes = new Size(LowLastFiveMinutes, SizeUnit.Bytes), SinceStartup = new Size(LowSinceStartup, SizeUnit.Bytes) } } }); } catch (Exception e) { if (Logger.IsInfoEnabled) { Logger.Info("Error while trying to get available memory, will stop trying and report that there is 256MB free only from now on", e); } _failedToGetAvailablePhysicalMemory = true; return(FailedResult); } }
private static unsafe MemoryInfoResult GetMemoryInfoMacOs(Process process, bool extended) { var mib = new[] { (int)TopLevelIdentifiers.CTL_HW, (int)CtkHwIdentifiers.HW_MEMSIZE }; ulong physicalMemory = 0; var len = sizeof(ulong); if (macSyscall.sysctl(mib, 2, &physicalMemory, &len, null, UIntPtr.Zero) != 0) { if (Logger.IsInfoEnabled) { Logger.Info("Failure when trying to read physical memory info from MacOS, error code was: " + Marshal.GetLastWin32Error()); } return(FailedResult); } uint pageSize; var vmStats = new vm_statistics64(); var machPort = macSyscall.mach_host_self(); var count = sizeof(vm_statistics64) / sizeof(uint); if (macSyscall.host_page_size(machPort, &pageSize) != 0 || macSyscall.host_statistics64(machPort, (int)Flavor.HOST_VM_INFO64, &vmStats, &count) != 0) { if (Logger.IsInfoEnabled) { Logger.Info("Failure when trying to get vm_stats from MacOS, error code was: " + Marshal.GetLastWin32Error()); } return(FailedResult); } // swap usage var swapu = new xsw_usage(); len = sizeof(xsw_usage); mib = new[] { (int)TopLevelIdentifiers.CTL_VM, (int)CtlVmIdentifiers.VM_SWAPUSAGE }; if (macSyscall.sysctl(mib, 2, &swapu, &len, null, UIntPtr.Zero) != 0) { if (Logger.IsInfoEnabled) { Logger.Info("Failure when trying to read swap info from MacOS, error code was: " + Marshal.GetLastWin32Error()); } return(FailedResult); } var totalPhysicalMemory = new Size((long)physicalMemory, SizeUnit.Bytes); /* Free memory: This is RAM that's not being used. * Wired memory: Information in this memory can't be moved to the hard disk, so it must stay in RAM. The amount of Wired memory depends on the applications you are using. * Active memory: This information is currently in memory, and has been recently used. * Inactive memory: This information in memory is not actively being used, but was recently used. */ var availableRamInBytes = new Size((vmStats.FreePagesCount + vmStats.InactivePagesCount) * pageSize, SizeUnit.Bytes); // there is no commited memory value in OSX, // this is an approximation: wired + active + swap used var commitedMemoryInBytes = (vmStats.WirePagesCount + vmStats.ActivePagesCount) * pageSize + (long)swapu.xsu_used; var commitedMemory = new Size(commitedMemoryInBytes, SizeUnit.Bytes); // commit limit: physical memory + swap var commitLimit = new Size((long)(physicalMemory + swapu.xsu_total), SizeUnit.Bytes); var availableWithoutTotalCleanMemory = availableRamInBytes; // mac (unlike other linux distros) does calculate accurate available memory var workingSet = new Size(process?.WorkingSet64 ?? 0, SizeUnit.Bytes); return(BuildPosixMemoryInfoResult(availableRamInBytes, totalPhysicalMemory, commitedMemory, commitLimit, availableWithoutTotalCleanMemory, Size.Zero, workingSet, extended)); }
public static unsafe MemoryInfoResult GetMemoryInfo() { if (_failedToGetAvailablePhysicalMemory) { if (Logger.IsInfoEnabled) { Logger.Info("Because of a previous error in getting available memory, we are now lying and saying we have 256MB free"); } return(FailedResult); } try { if (PlatformDetails.RunningOnPosix == false) { // windows var memoryStatus = new MemoryStatusEx { dwLength = (uint)sizeof(MemoryStatusEx) }; if (GlobalMemoryStatusEx(&memoryStatus) == false) { if (Logger.IsInfoEnabled) { Logger.Info("Failure when trying to read memory info from Windows, error code is: " + Marshal.GetLastWin32Error()); } return(FailedResult); } if (GetPhysicallyInstalledSystemMemory(out var installedMemoryInKb) == false) { installedMemoryInKb = (long)memoryStatus.ullTotalPhys; } SetMemoryRecords((long)memoryStatus.ullAvailPhys); return(new MemoryInfoResult { AvailableMemory = new Size((long)memoryStatus.ullAvailPhys, SizeUnit.Bytes), TotalPhysicalMemory = new Size((long)memoryStatus.ullTotalPhys, SizeUnit.Bytes), InstalledMemory = new Size(installedMemoryInKb, SizeUnit.Kilobytes), MemoryUsageRecords = new MemoryInfoResult.MemoryUsageLowHigh { High = new MemoryInfoResult.MemoryUsageIntervals { LastOneMinute = new Size(HighLastOneMinute, SizeUnit.Bytes), LastFiveMinutes = new Size(HighLastFiveMinutes, SizeUnit.Bytes), SinceStartup = new Size(HighSinceStartup, SizeUnit.Bytes) }, Low = new MemoryInfoResult.MemoryUsageIntervals { LastOneMinute = new Size(LowLastOneMinute, SizeUnit.Bytes), LastFiveMinutes = new Size(LowLastFiveMinutes, SizeUnit.Bytes), SinceStartup = new Size(LowSinceStartup, SizeUnit.Bytes) } } }); } // read both cgroup and sysinfo memory stats, and use the lowest if applicable var cgroupMemoryLimit = KernelVirtualFileSystemUtils.ReadNumberFromCgroupFile("/sys/fs/cgroup/memory/memory.limit_in_bytes"); var cgroupMemoryUsage = KernelVirtualFileSystemUtils.ReadNumberFromCgroupFile("/sys/fs/cgroup/memory/memory.usage_in_bytes"); ulong availableRamInBytes; ulong totalPhysicalMemoryInBytes; if (PlatformDetails.RunningOnMacOsx == false) { // linux var info = new sysinfo_t(); if (Syscall.sysinfo(ref info) != 0) { if (Logger.IsInfoEnabled) { Logger.Info("Failure when trying to read memory info from posix, error code was: " + Marshal.GetLastWin32Error()); } return(FailedResult); } availableRamInBytes = (ulong)GetAvailableMemoryFromProcMemInfo(); totalPhysicalMemoryInBytes = info.TotalRam; } else { // macOS var mib = new[] { (int)TopLevelIdentifiersMacOs.CTL_HW, (int)CtkHwIdentifiersMacOs.HW_MEMSIZE }; ulong physicalMemory = 0; var len = sizeof(ulong); if (Syscall.sysctl(mib, 2, &physicalMemory, &len, null, UIntPtr.Zero) != 0) { if (Logger.IsInfoEnabled) { Logger.Info("Failure when trying to read physical memory info from MacOS, error code was: " + Marshal.GetLastWin32Error()); } return(FailedResult); } totalPhysicalMemoryInBytes = physicalMemory; uint pageSize; var vmStats = new vm_statistics64(); var machPort = Syscall.mach_host_self(); var count = sizeof(vm_statistics64) / sizeof(uint); if (Syscall.host_page_size(machPort, &pageSize) != 0 || Syscall.host_statistics64(machPort, (int)FlavorMacOs.HOST_VM_INFO64, &vmStats, &count) != 0) { if (Logger.IsInfoEnabled) { Logger.Info("Failure when trying to get vm_stats from MacOS, error code was: " + Marshal.GetLastWin32Error()); } return(FailedResult); } availableRamInBytes = (vmStats.FreePagesCount + vmStats.InactivePagesCount) * (ulong)pageSize; } Size availableRam, totalPhysicalMemory; if (cgroupMemoryLimit < (long)totalPhysicalMemoryInBytes) { availableRam = new Size(cgroupMemoryLimit - cgroupMemoryUsage, SizeUnit.Bytes); totalPhysicalMemory = new Size(cgroupMemoryLimit, SizeUnit.Bytes); } else { availableRam = new Size((long)availableRamInBytes, SizeUnit.Bytes); totalPhysicalMemory = new Size((long)totalPhysicalMemoryInBytes, SizeUnit.Bytes); } SetMemoryRecords((long)availableRamInBytes); return(new MemoryInfoResult { AvailableMemory = availableRam, TotalPhysicalMemory = totalPhysicalMemory, //TODO: http://issues.hibernatingrhinos.com/issue/RavenDB-8468 InstalledMemory = totalPhysicalMemory, MemoryUsageRecords = new MemoryInfoResult.MemoryUsageLowHigh { High = new MemoryInfoResult.MemoryUsageIntervals { LastOneMinute = new Size(HighLastOneMinute, SizeUnit.Bytes), LastFiveMinutes = new Size(HighLastFiveMinutes, SizeUnit.Bytes), SinceStartup = new Size(HighSinceStartup, SizeUnit.Bytes) }, Low = new MemoryInfoResult.MemoryUsageIntervals { LastOneMinute = new Size(LowLastOneMinute, SizeUnit.Bytes), LastFiveMinutes = new Size(LowLastFiveMinutes, SizeUnit.Bytes), SinceStartup = new Size(LowSinceStartup, SizeUnit.Bytes) } } }); } catch (Exception e) { if (Logger.IsInfoEnabled) { Logger.Info("Error while trying to get available memory, will stop trying and report that there is 256MB free only from now on", e); } _failedToGetAvailablePhysicalMemory = true; return(FailedResult); } }