Java获取Linux系统信息 包括 CPU 内存 硬盘等使用情况 无依赖原生代码实现 home 编辑时间 2019/09/04 ![](/api/file/getImage?fileId=5d6f667516199b044f000d59) ## 需求 通过java接口实现简单的linux系统实时监控, 希望尽可能不增加系统算力和内存负担的基础上, 获取到系统信息,方便前端用图表来显示系统情况 ## 代码实现 说明:为减少查询本身带来的消耗,基本用java和linux原生语法,没用第三方依赖,代码中的唯一依赖的`StringUtils`,只是做非空判断 例如 ```java if (StringUtils.isNotBlank(string)) { } // 等价于 if (string != null && !"".equals(string)) { } ``` `LinuxUtils.java` ```java import org.apache.commons.lang.StringUtils; import java.io.*; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class LinuxUtils { /** * java执行linux命令 */ public String exec(String cmd) { try { String[] cmdA = {"/bin/sh", "-c", cmd}; Process process = Runtime.getRuntime().exec(cmdA); LineNumberReader br = new LineNumberReader(new InputStreamReader( process.getInputStream())); StringBuffer sb = new StringBuffer(); String line; while ((line = br.readLine()) != null) { sb.append(line).append("\n"); } return sb.toString(); } catch (Exception e) { e.printStackTrace(); } return null; } /** * 格式化linux返回 * 返回一个二维数组 */ public List<List<String>> format(String string) { List<List<String>> result = new ArrayList<>(); if (StringUtils.isNotBlank(string)) { String[] lines = string.split("\n"); for (String line : lines) { String[] strings = line.split(" "); List<String> temp = new ArrayList<>(); for (String str : strings) { if (StringUtils.isNotBlank(str)) { temp.add(str); } } result.add(temp); } } return result; } /** * 获取linux下 系统盘使用情况 */ public Map<String, Object> getDeskInfo() { Map<String, Object> result = new HashMap<>(); try { String info = exec("df"); List<List<String>> lists = format(info); for (List<String> list : lists) { if (list.size() >= 6 && "/".equals(list.get(5))) { for (int i = 0; i < list.size(); i++) { // 文件系统名称 result.put("diskName", list.get(0)); // 总空间 result.put("total", list.get(1)); // 已用 result.put("used", list.get(2)); // 可用 result.put("free", list.get(3)); // 百分比 result.put("useRate", list.get(4)); } } } } catch (Exception e) { e.printStackTrace(); } return result; } /** * 获取linux下 内存使用情况 * mem 为内存 * swap为交换区 */ public Map<String, Object> getRamInfo() { Map<String, Object> result = new HashMap<>(); try { String info = exec("free"); List<List<String>> lists = format(info); for (List<String> list : lists) { if (StringUtils.isNotBlank(list.get(0)) && list.get(0).toLowerCase().contains("mem")) { Map<String, Object> mem = new HashMap<>(); mem.put("total", list.get(1)); mem.put("used", list.get(2)); mem.put("free", list.get(3)); mem.put("shared", list.get(4)); mem.put("cache", list.get(5)); mem.put("available", list.get(6)); result.put("mem", mem); } else if (StringUtils.isNotBlank(list.get(0)) && list.get(0).toLowerCase().contains("swap")) { Map<String, Object> swap = new HashMap<>(); swap.put("total", list.get(1)); swap.put("used", list.get(2)); swap.put("free", list.get(3)); result.put("swap", swap); } } } catch ( Exception e) { e.printStackTrace(); } return result; } /** * 获取linux下 CPU使用情况 (使用top -b -n 1 实现,亲测不是十分准确,暂未使用) */ public Map<String, Object> getCPUInfoByTop() { Map<String, Object> result = new HashMap<>(); try { String info = exec("top -b -n 1 | sed -n '3p'"); String[] strings = info.split(":")[1].split(","); for (String string : strings) { if (StringUtils.isNotBlank(string) && string.toLowerCase().contains("id")) { String free = string.replace("id", "").trim(); result.put("free", free); String used = String.valueOf((10000 - Double.parseDouble(free) * 100) / 100); result.put("used", used); } } } catch ( Exception e) { e.printStackTrace(); } return result; } /** * 获取linux下 CPU使用情况 通过采集两次/proc/stat 计算CPU差值对比实现 * 参考: * https://www.cnblogs.com/shihaiming/p/7048264.html * https://www.cnblogs.com/gisblogs/p/3985393.html */ public Map<String, Object> getCPUInfo() { Map<String, Object> result = new HashMap<>(); try { String info = exec("cat /proc/stat"); List<String> cpu1 = format(info).get(0); // 间隔时间 推荐设置在 200 - 5000 毫秒之间 (小了不准 大了太慢) Thread.sleep(200); info = exec("cat /proc/stat"); List<String> cpu2 = format(info).get(0); // 用初中数学优化了一下网上的算法 float total = Float.parseFloat(cpu2.get(1)) - Float.parseFloat(cpu1.get(1)) + Float.parseFloat(cpu2.get(2)) - Float.parseFloat(cpu1.get(2)) + Float.parseFloat(cpu2.get(3)) - Float.parseFloat(cpu1.get(3)); float totalidle = total + Float.parseFloat(cpu2.get(4)) - Float.parseFloat(cpu1.get(4)); float useRate = (total / totalidle) * 100; result.put("useRate", useRate); } catch ( Exception e) { e.printStackTrace(); } return result; } public static void main(String[] args) { long time = System.currentTimeMillis(); LinuxUtils linuxUtils = new LinuxUtils(); System.out.println(linuxUtils.getDeskInfo()); System.out.println(linuxUtils.getRamInfo()); System.out.println(linuxUtils.getCPUInfo()); System.out.println("消耗时间:" + (System.currentTimeMillis() - time) / 1000.0 + "秒"); } } ``` ### 运行结果 ```shell {diskName=/dev/nvme0n1p5, total=105306896, used=44633952, useRate=45%, free=55280560} {mem={shared=120712, total=3950000, cache=639268, available=809536, used=2774656, free=536076}, swap={total=8388604, used=3328976, free=5059628}} {useRate=70.0} 消耗时间:0.277秒 ``` 送人玫瑰,手留余香 赞赏 Wechat Pay Alipay 基于Jgit 实现java自动化操作git 简单功能 Linux Deepin 15.11 安装PxCook 第二弹!基于PlayOnLinux