View Javadoc
1   /*
2    * Copyright 2016-2022 The OSHI Project Contributors
3    * SPDX-License-Identifier: MIT
4    */
5   package oshi.hardware.platform.unix.freebsd;
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 oshi.annotation.concurrent.ThreadSafe;
13  import oshi.hardware.VirtualMemory;
14  import oshi.hardware.common.AbstractGlobalMemory;
15  import oshi.util.ExecutingCommand;
16  import oshi.util.ParseUtil;
17  import oshi.util.platform.unix.freebsd.BsdSysctlUtil;
18  
19  /**
20   * Memory obtained by sysctl vm.stats
21   */
22  @ThreadSafe
23  final class FreeBsdGlobalMemory extends AbstractGlobalMemory {
24  
25      private final Supplier<Long> available = memoize(this::queryVmStats, defaultExpiration());
26  
27      private final Supplier<Long> total = memoize(FreeBsdGlobalMemory::queryPhysMem);
28  
29      private final Supplier<Long> pageSize = memoize(FreeBsdGlobalMemory::queryPageSize);
30  
31      private final Supplier<VirtualMemory> vm = memoize(this::createVirtualMemory);
32  
33      @Override
34      public long getAvailable() {
35          return available.get();
36      }
37  
38      @Override
39      public long getTotal() {
40          return total.get();
41      }
42  
43      @Override
44      public long getPageSize() {
45          return pageSize.get();
46      }
47  
48      @Override
49      public VirtualMemory getVirtualMemory() {
50          return vm.get();
51      }
52  
53      private long queryVmStats() {
54          // cached removed in FreeBSD 12 but was always set to 0
55          int inactive = BsdSysctlUtil.sysctl("vm.stats.vm.v_inactive_count", 0);
56          int free = BsdSysctlUtil.sysctl("vm.stats.vm.v_free_count", 0);
57          return (inactive + free) * getPageSize();
58      }
59  
60      private static long queryPhysMem() {
61          return BsdSysctlUtil.sysctl("hw.physmem", 0L);
62      }
63  
64      private static long queryPageSize() {
65          // sysctl hw.pagesize doesn't work on FreeBSD 13
66          return ParseUtil.parseLongOrDefault(ExecutingCommand.getFirstAnswer("sysconf PAGESIZE"), 4096L);
67      }
68  
69      private VirtualMemory createVirtualMemory() {
70          return new FreeBsdVirtualMemory(this);
71      }
72  }