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

如何通过Shell准确测量R语言多线程程序的内存使用情况?

问题:ps统计用户进程内存占比总和超100%,与free结果不符

背景

我用Shell脚本监控系统资源并发送告警,核心依赖以下命令统计指定用户的进程内存占比总和:

ps -u "$user" --no-headers -o pmem | awk '{sum += $1} END {print sum}'

多数场景下运行正常,但近期发现统计结果异常。

复现方式

在刚重启的干净系统中运行以下R代码,排除其他进程干扰:

library(data.table)
library(parallel)

set.seed(123)
n_rows <- 1e7  
n_cols <- 1000
# 内存占用较高,可根据自身系统调整,需达到可用内存的1/30至1/10以复现问题
dt <- data.table(matrix(runif(n_rows * n_cols), nrow = n_rows, ncol = n_cols))

memory_usage <- object.size(dt)
format(memory_usage, units = "auto")

worker_function <- function(data) {
  row_sums <- rowSums(data)
  # 休眠1000秒,方便运行Shell命令测试
  Sys.sleep(1000)
  return(row_sums)
}

n_threads <- 10
results <- mclapply(1:n_threads, function(x) worker_function(dt), mc.cores = n_threads)

现象对比

  1. 执行以下命令统计用户进程内存占比总和,结果超过100%:
ps -u "$user" --no-headers -o pmem | awk '{sum += $1} END {print sum}'
# 输出示例:113.9
  1. 用free -h查看系统实际内存使用:
    我的系统配置为1.5 TiB物理内存、2.0 GiB交换空间,free显示仅使用了645/1500 GiB,占比不足50%。

原因分析

ps的pmem字段统计的是进程包含共享内存在内的内存占比,当多个进程共享同一块内存(比如示例中R的mclapply创建的子进程共享父进程的dt数据)时,共享内存会被每个进程重复计算,导致总和超过100%。而free统计的是系统实际已使用的物理内存,共享内存仅被计算一次,因此两者结果存在差异。

解决方案

要准确统计用户实际占用的内存,需使用能处理共享内存重复计算的工具,比如smem:

smem -t -k -u -p -U "$user" | tail -1 | awk '{print $5}'

该命令会自动扣除共享内存的重复统计,结果更贴近系统实际内存占用情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 15:10:06