1
2
3
4
5 package oshi.hardware.platform.mac;
6
7 import static oshi.util.Memoizer.defaultExpiration;
8 import static oshi.util.Memoizer.memoize;
9
10 import java.util.function.Supplier;
11
12 import org.slf4j.Logger;
13 import org.slf4j.LoggerFactory;
14
15 import com.sun.jna.Native;
16 import com.sun.jna.platform.mac.SystemB;
17
18 import oshi.annotation.concurrent.ThreadSafe;
19 import oshi.hardware.common.AbstractVirtualMemory;
20 import oshi.jna.ByRef.CloseableIntByReference;
21 import oshi.jna.Struct.CloseableVMStatistics;
22 import oshi.jna.Struct.CloseableXswUsage;
23 import oshi.util.ParseUtil;
24 import oshi.util.platform.mac.SysctlUtil;
25 import oshi.util.tuples.Pair;
26
27
28
29
30 @ThreadSafe
31 final class MacVirtualMemory extends AbstractVirtualMemory {
32
33 private static final Logger LOG = LoggerFactory.getLogger(MacVirtualMemory.class);
34
35 private final MacGlobalMemory global;
36
37 private final Supplier<Pair<Long, Long>> usedTotal = memoize(MacVirtualMemory::querySwapUsage, defaultExpiration());
38
39 private final Supplier<Pair<Long, Long>> inOut = memoize(MacVirtualMemory::queryVmStat, defaultExpiration());
40
41
42
43
44
45
46 MacVirtualMemory(MacGlobalMemory macGlobalMemory) {
47 this.global = macGlobalMemory;
48 }
49
50 @Override
51 public long getSwapUsed() {
52 return usedTotal.get().getA();
53 }
54
55 @Override
56 public long getSwapTotal() {
57 return usedTotal.get().getB();
58 }
59
60 @Override
61 public long getVirtualMax() {
62 return this.global.getTotal() + getSwapTotal();
63 }
64
65 @Override
66 public long getVirtualInUse() {
67 return this.global.getTotal() - this.global.getAvailable() + getSwapUsed();
68 }
69
70 @Override
71 public long getSwapPagesIn() {
72 return inOut.get().getA();
73 }
74
75 @Override
76 public long getSwapPagesOut() {
77 return inOut.get().getB();
78 }
79
80 private static Pair<Long, Long> querySwapUsage() {
81 long swapUsed = 0L;
82 long swapTotal = 0L;
83 try (CloseableXswUsage xswUsage = new CloseableXswUsage()) {
84 if (SysctlUtil.sysctl("vm.swapusage", xswUsage)) {
85 swapUsed = xswUsage.xsu_used;
86 swapTotal = xswUsage.xsu_total;
87 }
88 }
89 return new Pair<>(swapUsed, swapTotal);
90 }
91
92 private static Pair<Long, Long> queryVmStat() {
93 long swapPagesIn = 0L;
94 long swapPagesOut = 0L;
95 try (CloseableVMStatistics vmStats = new CloseableVMStatistics();
96 CloseableIntByReference size = new CloseableIntByReference(vmStats.size() / SystemB.INT_SIZE)) {
97 if (0 == SystemB.INSTANCE.host_statistics(SystemB.INSTANCE.mach_host_self(), SystemB.HOST_VM_INFO, vmStats,
98 size)) {
99 swapPagesIn = ParseUtil.unsignedIntToLong(vmStats.pageins);
100 swapPagesOut = ParseUtil.unsignedIntToLong(vmStats.pageouts);
101 } else {
102 LOG.error("Failed to get host VM info. Error code: {}", Native.getLastError());
103 }
104 }
105 return new Pair<>(swapPagesIn, swapPagesOut);
106 }
107 }