You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Sigar ProcCpu获取单个进程CPU占比始终返回0问题求助

解决Sigar在Windows下获取单个进程CPU使用率始终为0的问题

我之前也踩过Sigar这个坑!系统整体CPU能正常获取,但单个进程的CPU使用率一直返回0,核心原因其实是Sigar计算进程CPU使用率需要两次采样的差值,单次调用gather()根本算不出真实的使用率。

问题根源

Sigar的ProcCpu和MultiProcCpu类的getPercent()方法,是通过对比两次采样的进程CPU累计运行时间,除以两次采样的系统时间差来计算使用率的。第一次调用gather()时,它只记录了当前的初始时间戳,没有之前的参考数据,所以返回0是设计如此,不是你的代码写错了。

解决办法

给每个进程做两次gather()采样,中间间隔一小段时间(推荐500ms~1s),这样第二次采样后就能算出正确的使用率了。下面是修改后的代码示例:

修正后的Java进程CPU获取逻辑

while (i < javaPIDs.length) {
    Long javaPID = javaPIDs[i];
    ProcessInfo javaProcess = new ProcessInfo();
    javaProcess.setPid(javaPID);
    javaProcess.setName("Java");

    // 内存获取逻辑保持不变
    ProcMem javaMem = new ProcMem();
    javaMem.gather(sigar, javaPID);
    javaProcess.setMemoryUsage(javaMem.getResident() / 1024 / 1024);

    // 核心修改:两次采样计算CPU使用率
    MultiProcCpu javaCpu = new MultiProcCpu();
    // 第一次采样,记录初始CPU时间
    javaCpu.gather(sigar, javaPID);
    // 等待500ms,让系统有足够的CPU时间变化
    try {
        Thread.sleep(500);
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt(); // 不要吞中断
    }
    // 第二次采样,更新最新CPU时间
    javaCpu.gather(sigar, javaPID);
    // 现在getPercent()能返回正确的使用率了
    javaProcess.setCpuUsage(String.format("%.2f", javaCpu.getPercent() * 100));

    processes.add(javaProcess);
    i++;
}

修正后的SQL Server进程CPU获取逻辑

if (sqlPID != null) {
    ProcessInfo sqlProcess = new ProcessInfo();
    sqlProcess.setPid(sqlPID);
    sqlProcess.setName("SQL Server");

    ProcMem sqlMem = new ProcMem();
    sqlMem.gather(sigar, sqlPID);
    sqlProcess.setMemoryUsage(sqlMem.getResident() / 1024 / 1024);

    MultiProcCpu sqlCpu = new MultiProcCpu();
    sqlCpu.gather(sigar, sqlPID);
    try {
        Thread.sleep(500);
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }
    sqlCpu.gather(sigar, sqlPID);
    sqlProcess.setCpuUsage(String.format("%.2f", sqlCpu.getPercent() * 100));

    processes.add(sqlProcess);
}

额外注意事项

  • 避免在Web请求线程中直接sleep:如果这是Web项目,直接在请求处理线程sleep会阻塞请求,建议用异步任务(比如Spring的@Async)定期采样进程信息,把结果缓存起来供页面调用。
  • 调整等待时间:500ms是比较均衡的取值,太短可能导致CPU时间变化太小,计算结果不准确;太长会影响响应速度。
  • 权限问题:确保你的程序有足够权限读取进程信息,Windows下可以尝试以管理员身份运行程序,避免权限不足导致的数据获取异常。
  • Sigar版本:尽量使用最新的稳定版Sigar,旧版本可能存在Windows平台的兼容性bug。

内容的提问来源于stack exchange,提问作者Martin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:06:55