Skip to content

Commit 40f1092

Browse files
committed
ram_free,total: fallbacks
1 parent b77c412 commit 40f1092

File tree

3 files changed

+74
-26
lines changed

3 files changed

+74
-26
lines changed

+stdlib/private/py_ram_free.m

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
function n = py_ram_free()
2+
3+
try
4+
vm = py.psutil.virtual_memory();
5+
n = uint64(vm.available);
6+
catch
7+
n = 0;
8+
end
9+
10+
end

+stdlib/ram_free.m

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
%% RAM_FREE get free physical RAM
2+
% What "free" memory means has many definitions across computing platforms.
3+
% The user must consider total memory and monitor swap usage.
24
%
35
% get free physical RAM across operating systems
46
% https://docs.oracle.com/en/java/javase/21/docs/api/jdk.management/com/sun/management/OperatingSystemMXBean.html#getFreeMemorySize()
@@ -7,30 +9,44 @@
79
% * freebytes: free physical RAM [bytes]
810
%
911
% This is done using Java on non-Windows platforms.
10-
% VisualBasic (needs Windows) is needed to do this with .NET, so we use builtin memory() on Windows.
12+
%
13+
% VisualBasic (needs Windows) is needed to do this with .NET,
14+
%
15+
% builtin memory() on Windows includes swap. The user could do that themselves.
16+
%
17+
% we installed use Java or Python psutil, which are consistent with each other.
18+
%
19+
% Fallback is to shell commands.
1120

1221
function bytes = ram_free()
1322

14-
bytes = 0;
23+
if stdlib.has_java()
24+
bytes = ram_free_java();
25+
elseif stdlib.has_python()
26+
bytes = py_ram_free();
27+
else
28+
bytes = ram_free_system();
29+
end
1530

16-
try
17-
% memory() was added cross-platform to Octave ~ 2021.
18-
% Matlab memory() at least through R2025a is still Windows only.
19-
m = memory();
31+
bytes = uint64(bytes);
2032

21-
bytes = m.MemAvailableAllArrays;
33+
end
34+
35+
36+
function bytes = ram_free_system()
2237

23-
catch e
24-
switch e.identifier
25-
case {'MATLAB:memory:unsupported', 'Octave:undefined-function'}
26-
if stdlib.has_java()
27-
bytes = ram_free_java();
28-
end
29-
otherwise, rethrow(e)
30-
end
38+
if ispc()
39+
cmd = 'pwsh -c "(Get-CimInstance -ClassName CIM_OperatingSystem).FreePhysicalMemory * 1KB"';
40+
elseif ismac()
41+
cmd = 'sysctl -n hw.memsize';
42+
else
43+
cmd = "free -b | awk '/Mem:/ {print $4}'";
3144
end
3245

33-
bytes = uint64(bytes);
46+
[s, m] = system(cmd);
47+
if s == 0
48+
bytes = str2double(m);
49+
end
3450

3551
end
3652

+stdlib/ram_total.m

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,29 +8,51 @@
88

99
function bytes = ram_total()
1010

11-
bytes = uint64(0);
12-
1311

1412
if stdlib.dotnet_api() >= 6
1513
% .NET is 2-3x faster than Java for this
1614
% https://learn.microsoft.com/en-us/dotnet/api/system.gcmemoryinfo.totalavailablememorybytes
1715
bytes = System.GC.GetGCMemoryInfo().TotalAvailableMemoryBytes;
1816
elseif stdlib.has_java()
17+
bytes = ram_total_java();
18+
else
19+
bytes = ram_total_system();
20+
end
1921

20-
% https://docs.oracle.com/en/java/javase/21/docs/api/jdk.management/com/sun/management/OperatingSystemMXBean.html#getTotalMemorySize()
22+
bytes = uint64(bytes);
2123

22-
b = javaMethod("getOperatingSystemMXBean", "java.lang.management.ManagementFactory");
24+
end
2325

24-
if stdlib.java_api() < 14
25-
bytes = b.getTotalPhysicalMemorySize();
26-
else
27-
bytes = b.getTotalMemorySize();
28-
end
26+
27+
function bytes = ram_total_system()
28+
29+
if ispc()
30+
cmd = 'pwsh -c "(Get-CimInstance -ClassName Win32_ComputerSystem).TotalPhysicalMemory"';
31+
elseif ismac()
32+
cmd = 'sysctl -n hw.memsize';
33+
else
34+
cmd = "free -b | awk '/Mem:/ {print $4}'";
2935
end
3036

31-
bytes = uint64(bytes);
37+
[s, m] = system(cmd);
38+
if s == 0
39+
bytes = str2double(m);
40+
end
3241

3342
end
3443

3544

45+
function bytes = ram_total_java()
46+
% https://docs.oracle.com/en/java/javase/21/docs/api/jdk.management/com/sun/management/OperatingSystemMXBean.html#getTotalMemorySize()
47+
48+
b = javaMethod("getOperatingSystemMXBean", "java.lang.management.ManagementFactory");
49+
50+
if stdlib.java_api() < 14
51+
bytes = b.getTotalPhysicalMemorySize();
52+
else
53+
bytes = b.getTotalMemorySize();
54+
end
55+
56+
end
57+
3658
%!assert(ram_total()>0)

0 commit comments

Comments
 (0)