Skip to content

Commit

Permalink
Expose memory page size to API. (#503)
Browse files Browse the repository at this point in the history
  • Loading branch information
dbwiddis authored May 31, 2018
1 parent 30d5819 commit 317ca78
Show file tree
Hide file tree
Showing 14 changed files with 80 additions and 18 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
================
* [#489](https://github.com/oshi/oshi/pull/489): Switch from WMI to native methods for most Windows Process data. - [@dbwiddis](https://github.com/dbwiddis).
* [#501](https://github.com/oshi/oshi/pull/501): Added HWDiskStore.updateDiskStats. - [@cjbrowne](https://github.com/cjbrowne).
* [#503](https://github.com/oshi/oshi/pull/503): Expose memory page size to API. - [@dbwiddis](https://github.com/dbwiddis).
* Your contribution here.

3.5.0 (4/15/18)
Expand Down
7 changes: 7 additions & 0 deletions oshi-core/src/main/java/oshi/hardware/GlobalMemory.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,11 @@ public interface GlobalMemory extends Serializable {
* @return Swap used in bytes
*/
long getSwapUsed();

/**
* The number of bytes in a memory page
*
* @return Page size in bytes.
*/
long getPageSize();
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ public abstract class AbstractGlobalMemory implements GlobalMemory {
protected long memAvailable = 0L;
protected long swapTotal = 0L;
protected long swapUsed = 0L;
protected long pageSize = 0L;

/**
* Updates physical memory instance variables.
Expand Down Expand Up @@ -82,4 +83,15 @@ public long getSwapTotal() {
updateSwap();
return this.swapTotal;
}

/**
* {@inheritDoc}
*/
@Override
public long getPageSize() {
if (this.pageSize == 0) {
updateMeminfo();
}
return this.pageSize;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,14 @@

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.sun.jna.Native;

import oshi.hardware.common.AbstractGlobalMemory;
import oshi.jna.platform.linux.Libc;
import oshi.jna.platform.linux.Libc.Sysinfo;
import oshi.util.FileUtil;
import oshi.util.ParseUtil;

Expand All @@ -34,6 +41,8 @@ public class LinuxGlobalMemory extends AbstractGlobalMemory {

private static final long serialVersionUID = 1L;

private static final Logger LOG = LoggerFactory.getLogger(LinuxGlobalMemory.class);

// Values read from /proc/meminfo used for other calculations
private long memFree = 0;
private long activeFile = 0;
Expand All @@ -43,6 +52,19 @@ public class LinuxGlobalMemory extends AbstractGlobalMemory {

private long lastUpdate = 0;

public LinuxGlobalMemory() {
try {
Sysinfo info = new Sysinfo();
if (0 == Libc.INSTANCE.sysinfo(info)) {
this.pageSize = info.mem_unit;
} else {
LOG.error("Failed to get sysinfo. Error code: {}", Native.getLastError());
}
} catch (UnsatisfiedLinkError | NoClassDefFoundError e) {
LOG.error("Failed to get mem_unit from sysinfo. {}", e);
}
}

/**
* Updates instance variables from reading /proc/meminfo no more frequently
* than every 100ms. While most of the information is available in the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,6 @@ public class MacGlobalMemory extends AbstractGlobalMemory {
private transient VMStatistics vmStats = new VMStatistics();
private long lastUpdateAvail = 0;

private long pageSize = 4096;

public MacGlobalMemory() {
long memory = SysctlUtil.sysctl("hw.memsize", -1L);
if (memory >= 0) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,21 +33,20 @@ public class FreeBsdGlobalMemory extends AbstractGlobalMemory {

private static final long serialVersionUID = 1L;

private static final long PAGESIZE = BsdSysctlUtil.sysctl("hw.pagesize", 4096);
public FreeBsdGlobalMemory() {
this.pageSize = BsdSysctlUtil.sysctl("hw.pagesize", 4096L);
this.memTotal = BsdSysctlUtil.sysctl("hw.physmem", 0L);
}

/**
* {@inheritDoc}
*/
@Override
protected void updateMeminfo() {
if (this.memTotal == 0L) {
this.memTotal = BsdSysctlUtil.sysctl("hw.physmem", 0L);
}
// get pages of available memory
long inactive = BsdSysctlUtil.sysctl("vm.stats.vm.v_inactive_count", 0L);
long cache = BsdSysctlUtil.sysctl("vm.stats.vm.v_cache_count", 0L);
long free = BsdSysctlUtil.sysctl("vm.stats.vm.v_free_count", 0L);
this.memAvailable = (inactive + cache + free) * PAGESIZE;
this.memAvailable = (inactive + cache + free) * this.pageSize;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,12 @@ public class SolarisGlobalMemory extends AbstractGlobalMemory {

private static final long serialVersionUID = 1L;

private static final long PAGESIZE = ParseUtil.parseLongOrDefault(ExecutingCommand.getFirstAnswer("pagesize"),
4096L);

private static final Pattern SWAPINFO = Pattern.compile(".+\\s(\\d+)K\\s+(\\d+)K$");

public SolarisGlobalMemory() {
this.pageSize = ParseUtil.parseLongOrDefault(ExecutingCommand.getFirstAnswer("pagesize"), 4096L);
}

/**
* {@inheritDoc}
*/
Expand All @@ -51,8 +52,8 @@ protected void updateMeminfo() {
Kstat ksp = KstatUtil.kstatLookup(null, -1, "system_pages");
// Set values
if (ksp != null && KstatUtil.kstatRead(ksp)) {
this.memAvailable = KstatUtil.kstatDataLookupLong(ksp, "availrmem") * PAGESIZE;
this.memTotal = KstatUtil.kstatDataLookupLong(ksp, "physmem") * PAGESIZE;
this.memAvailable = KstatUtil.kstatDataLookupLong(ksp, "availrmem") * this.pageSize;
this.memTotal = KstatUtil.kstatDataLookupLong(ksp, "physmem") * this.pageSize;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,10 @@ protected void updateMeminfo() {
LOG.error("Failed to get Performance Info. Error code: {}", Kernel32.INSTANCE.GetLastError());
return;
}
this.memAvailable = this.perfInfo.PageSize.longValue() * this.perfInfo.PhysicalAvailable.longValue();
this.memTotal = this.perfInfo.PageSize.longValue() * this.perfInfo.PhysicalTotal.longValue();
this.swapTotal = this.perfInfo.PageSize.longValue()
this.pageSize = this.perfInfo.PageSize.longValue();
this.memAvailable = this.pageSize * this.perfInfo.PhysicalAvailable.longValue();
this.memTotal = this.pageSize * this.perfInfo.PhysicalTotal.longValue();
this.swapTotal = this.pageSize
* (this.perfInfo.CommitLimit.longValue() - this.perfInfo.PhysicalTotal.longValue());
this.lastUpdate = now;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ public void testGlobalMemory() {
assertTrue(memory.getTotal() > 0);
assertTrue(memory.getAvailable() >= 0);
assertTrue(memory.getAvailable() <= memory.getTotal());
assertTrue(memory.getPageSize() > 0);

// Swap tests
assertTrue(memory.getSwapTotal() >= 0);
Expand Down
9 changes: 8 additions & 1 deletion oshi-json/src/main/java/oshi/json/hardware/GlobalMemory.java
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,14 @@ public interface GlobalMemory extends OshiJsonObject {
/**
* The current memory committed to the paging/swap file(s), in bytes
*
* @return Swap used in bytes
* @return Swap used in bytes.
*/
long getSwapUsed();

/**
* The number of bytes in a memory page
*
* @return Page size in bytes.
*/
long getPageSize();
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public class HWDiskStore extends AbstractOshiJsonObject implements Comparable<HW

private static final long serialVersionUID = 1L;

private static final Logger LOG = LoggerFactory.getLogger(NetworkIF.class);
private static final Logger LOG = LoggerFactory.getLogger(HWDiskStore.class);

private transient JsonBuilderFactory jsonFactory = Json.createBuilderFactory(null);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,14 @@ public long getSwapUsed() {
return this.memory.getSwapUsed();
}

/**
* {@inheritDoc}
*/
@Override
public long getPageSize() {
return this.memory.getPageSize();
}

/**
* {@inheritDoc}
*/
Expand All @@ -103,6 +111,9 @@ public JsonObject toJSON(Properties properties) {
if (PropertiesUtil.getBoolean(properties, "hardware.memory.swapUsed")) {
json.add("swapUsed", getSwapUsed());
}
if (PropertiesUtil.getBoolean(properties, "hardware.memory.pageSize")) {
json.add("pageSize", getPageSize());
}
return json.build();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ public void testGlobalMemory() {
assertTrue(memory.getTotal() > 0);
assertTrue(memory.getAvailable() >= 0);
assertTrue(memory.getAvailable() <= memory.getTotal());
assertTrue(memory.getPageSize() > 0);

// Swap tests
assertTrue(memory.getSwapTotal() >= 0);
Expand Down
1 change: 1 addition & 0 deletions oshi-json/src/test/resources/oshi.json.properties
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@
# hardware.memory.total = false
# hardware.memory.swapTotal = false
# hardware.memory.swapUsed = false
# hardware.memory.pageSize = false
# hardware.powerSources = false
# hardware.powerSources.name = false
# hardware.powerSources.remainingCapacity = false
Expand Down

0 comments on commit 317ca78

Please sign in to comment.