View Javadoc
1   /*
2    * Copyright 2019-2022 The OSHI Project Contributors
3    * SPDX-License-Identifier: MIT
4    */
5   package oshi.hardware.platform.unix.solaris;
6   
7   import static oshi.util.Memoizer.defaultExpiration;
8   import static oshi.util.Memoizer.memoize;
9   
10  import java.util.function.Supplier;
11  import java.util.regex.Matcher;
12  import java.util.regex.Pattern;
13  
14  import oshi.annotation.concurrent.ThreadSafe;
15  import oshi.driver.unix.solaris.kstat.SystemPages;
16  import oshi.hardware.common.AbstractVirtualMemory;
17  import oshi.util.ExecutingCommand;
18  import oshi.util.ParseUtil;
19  import oshi.util.tuples.Pair;
20  
21  /**
22   * Memory obtained by kstat and swap
23   */
24  @ThreadSafe
25  final class SolarisVirtualMemory extends AbstractVirtualMemory {
26  
27      private static final Pattern SWAP_INFO = Pattern.compile(".+\\s(\\d+)K\\s+(\\d+)K$");
28  
29      private final SolarisGlobalMemory global;
30  
31      // Physical
32      private final Supplier<Pair<Long, Long>> availTotal = memoize(SystemPages::queryAvailableTotal,
33              defaultExpiration());
34  
35      // Swap
36      private final Supplier<Pair<Long, Long>> usedTotal = memoize(SolarisVirtualMemory::querySwapInfo,
37              defaultExpiration());
38  
39      private final Supplier<Long> pagesIn = memoize(SolarisVirtualMemory::queryPagesIn, defaultExpiration());
40  
41      private final Supplier<Long> pagesOut = memoize(SolarisVirtualMemory::queryPagesOut, defaultExpiration());
42  
43      /**
44       * Constructor for SolarisVirtualMemory.
45       *
46       * @param solarisGlobalMemory The parent global memory class instantiating this
47       */
48      SolarisVirtualMemory(SolarisGlobalMemory solarisGlobalMemory) {
49          this.global = solarisGlobalMemory;
50      }
51  
52      @Override
53      public long getSwapUsed() {
54          return usedTotal.get().getA();
55      }
56  
57      @Override
58      public long getSwapTotal() {
59          return usedTotal.get().getB();
60      }
61  
62      @Override
63      public long getVirtualMax() {
64          return this.global.getPageSize() * availTotal.get().getB() + getSwapTotal();
65      }
66  
67      @Override
68      public long getVirtualInUse() {
69          return this.global.getPageSize() * (availTotal.get().getB() - availTotal.get().getA()) + getSwapUsed();
70      }
71  
72      @Override
73      public long getSwapPagesIn() {
74          return pagesIn.get();
75      }
76  
77      @Override
78      public long getSwapPagesOut() {
79          return pagesOut.get();
80      }
81  
82      private static long queryPagesIn() {
83          long swapPagesIn = 0L;
84          for (String s : ExecutingCommand.runNative("kstat -p cpu_stat:::pgswapin")) {
85              swapPagesIn += ParseUtil.parseLastLong(s, 0L);
86          }
87          return swapPagesIn;
88      }
89  
90      private static long queryPagesOut() {
91          long swapPagesOut = 0L;
92          for (String s : ExecutingCommand.runNative("kstat -p cpu_stat:::pgswapout")) {
93              swapPagesOut += ParseUtil.parseLastLong(s, 0L);
94          }
95          return swapPagesOut;
96      }
97  
98      private static Pair<Long, Long> querySwapInfo() {
99          long swapTotal = 0L;
100         long swapUsed = 0L;
101         String swap = ExecutingCommand.getAnswerAt("swap -lk", 1);
102         Matcher m = SWAP_INFO.matcher(swap);
103         if (m.matches()) {
104             swapTotal = ParseUtil.parseLongOrDefault(m.group(1), 0L) << 10;
105             swapUsed = swapTotal - (ParseUtil.parseLongOrDefault(m.group(2), 0L) << 10);
106         }
107         return new Pair<>(swapUsed, swapTotal);
108     }
109 }