GlobalMemory.java
/**
* Oshi (https://github.com/dblock/oshi)
*
* Copyright (c) 2010 - 2015 The Oshi Project Team
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* dblock[at]dblock[dot]org
* alessandro[at]perucchi[dot]org
* widdis[at]gmail[dot]com
* https://github.com/dblock/oshi/graphs/contributors
*/
package oshi.software.os.linux.proc;
import java.io.IOException;
import java.util.List;
import oshi.hardware.Memory;
import oshi.software.os.linux.Libc;
import oshi.software.os.linux.Libc.Sysinfo;
import oshi.util.FileUtil;
import com.sun.jna.LastErrorException;
import com.sun.jna.Native;
/**
* Memory obtained by /proc/meminfo and sysinfo.totalram
*
* @author alessandro[at]perucchi[dot]org
* @author widdis[at]gmail[dot]com
*/
public class GlobalMemory implements Memory {
private long totalMemory = 0;
@Override
public long getAvailable() {
long availableMemory = 0;
List<String> memInfo = null;
try {
memInfo = FileUtil.readFile("/proc/meminfo");
} catch (IOException e) {
System.err.println("Problem with: /proc/meminfo");
System.err.println(e.getMessage());
return availableMemory;
}
for (String checkLine : memInfo) {
// If we have MemAvailable, it trumps all. See code in
// https://git.kernel.org/cgit/linux/kernel/git/torvalds/
// linux.git/commit/?id=34e431b0ae398fc54ea69ff85ec700722c9da773
if (checkLine.startsWith("MemAvailable:")) {
String[] memorySplit = checkLine.split("\\s+");
availableMemory = parseMeminfo(memorySplit);
break;
} else
// Otherwise we combine MemFree + Active(file), Inactive(file), and
// SReclaimable. Free+cached is no longer appropriate. MemAvailable
// reduces these values using watermarks to estimate when swapping
// is prevented, omitted here for simplicity (assuming 0 swap).
if (checkLine.startsWith("MemFree:")) {
String[] memorySplit = checkLine.split("\\s+");
availableMemory += parseMeminfo(memorySplit);
} else if (checkLine.startsWith("Active(file):")) {
String[] memorySplit = checkLine.split("\\s+");
availableMemory += parseMeminfo(memorySplit);
} else if (checkLine.startsWith("Inactive(file):")) {
String[] memorySplit = checkLine.split("\\s+");
availableMemory += parseMeminfo(memorySplit);
} else if (checkLine.startsWith("SReclaimable:")) {
String[] memorySplit = checkLine.split("\\s+");
availableMemory += parseMeminfo(memorySplit);
}
}
return availableMemory;
}
@Override
public long getTotal() {
if (this.totalMemory == 0) {
Sysinfo info = new Sysinfo();
if (0 != Libc.INSTANCE.sysinfo(info))
throw new LastErrorException("Error code: "
+ Native.getLastError());
this.totalMemory = info.totalram.longValue() * info.mem_unit;
}
return this.totalMemory;
}
private long parseMeminfo(String[] memorySplit) {
if (memorySplit.length < 2) {
return 0l;
}
long memory = new Long(memorySplit[1]).longValue();
if (memorySplit.length > 2 && memorySplit[2].equals("kB")) {
memory *= 1024;
}
return memory;
}
}