Golang如何获取Linux系统中每个进程的内存使用情况
Golang如何获取Linux系统中每个进程的内存使用情况 如何从proc文件夹读取每个进程及其使用的RAM内存,
7 回复
这与 Go 有什么关系?
更多关于Golang如何获取Linux系统中每个进程的内存使用情况的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
我想使用Go语言读取Linux系统中每个正在运行的进程及其CPU使用率和内存使用情况
我无法从主函数获得所需的输出
哪个库提供 Unixprocess?
结构体名称为Unixprocess。
type Unixprocess struct {
pid int
name string
ppid int
binary string
state rune
status string
pgrp int
sid int
meminfo *MemInfoStat
}
func (p *Unixprocess) fillFromStatus() error {
return p.fillFromStatusWithContext(context.Background())
}
func (p *Unixprocess) fillFromStatusWithContext(ctx context.Context) error {
pid := p.pid
statPath := memory.HostProc(strconv.Itoa(int(pid)), "status")
contents, err := ioutil.ReadFile(statPath)
if err != nil {
return err
}
lines := strings.Split(string(contents), "\n")
//p.memInfo = &MemoryInfoStat{}
p.meminfo= &MemInfoStat{}
for _, line := range lines {
tabParts := strings.SplitN(line, "\t", 2)
if len(tabParts) < 2 {
continue
}
value := tabParts[1]
switch strings.TrimRight(tabParts[0], ":") {
case "PPid", "Ppid":
pval, err := strconv.ParseInt(value, 10, 32)
if err != nil {
return err
}
p.ppid = int(pval)
case "VmRSS":
value := strings.Trim(value, " kB") // remove last "kB"
v, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return err
}
p.meminfo.RSS=v* 1024
//p.memInfo.RSS = v * 1024
case "VmSize":
value := strings.Trim(value, " kB") // remove last "kB"
v, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return err
}
p.meminfo.VMS = v * 1024
case "VmSwap":
value := strings.Trim(value, " kB") // remove last "kB"
v, err := strconv.ParseUint(value, 10, 64)
if err != nil {
return err
}
p.meminfo.Swap = v * 1024
}
}
return nil
}
在Go语言中,可以通过读取Linux系统的/proc文件系统来获取每个进程的内存使用情况。/proc是一个虚拟文件系统,提供了内核和进程信息的实时访问。每个进程在/proc下有一个以进程ID(PID)命名的目录,其中status文件包含了内存使用数据。
以下是实现步骤和示例代码:
- 读取
/proc目录,获取所有进程的PID。 - 对于每个PID,读取
/proc/[PID]/status文件。 - 解析
status文件中的VmRSS字段(表示实际使用的物理内存,单位通常是kB)。 - 可选地,将内存值转换为更友好的单位(如MB或GB)。
示例代码:
package main
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strconv"
"strings"
)
// 获取所有进程的PID列表
func getPIDs() ([]int, error) {
var pids []int
files, err := ioutil.ReadDir("/proc")
if err != nil {
return nil, err
}
for _, file := range files {
if file.IsDir() {
pid, err := strconv.Atoi(file.Name())
if err == nil {
pids = append(pids, pid)
}
}
}
return pids, nil
}
// 读取指定PID的status文件并解析VmRSS值
func getProcessMemory(pid int) (uint64, error) {
statusPath := filepath.Join("/proc", strconv.Itoa(pid), "status")
data, err := ioutil.ReadFile(statusPath)
if err != nil {
return 0, err
}
lines := strings.Split(string(data), "\n")
for _, line := range lines {
if strings.HasPrefix(line, "VmRSS:") {
fields := strings.Fields(line)
if len(fields) >= 2 {
memKB, err := strconv.ParseUint(fields[1], 10, 64)
if err != nil {
return 0, err
}
return memKB, nil // 返回单位为kB
}
}
}
return 0, fmt.Errorf("VmRSS not found for PID %d", pid)
}
func main() {
pids, err := getPIDs()
if err != nil {
fmt.Printf("Error reading PIDs: %v\n", err)
return
}
for _, pid := range pids {
mem, err := getProcessMemory(pid)
if err != nil {
// 忽略无法读取的进程(如已终止)
continue
}
// 转换为MB显示
memMB := float64(mem) / 1024.0
fmt.Printf("PID: %d, Memory Usage: %.2f MB\n", pid, memMB)
}
}
代码说明:
getPIDs函数读取/proc目录,过滤出所有数字命名的目录(即PID)。getProcessMemory函数读取指定PID的status文件,查找VmRSS行并解析其值(单位kB)。- 主函数遍历所有PID,获取内存使用并输出为MB。
注意:
- 某些进程可能无法访问(如权限不足或进程已终止),代码中通过
continue跳过错误。 VmRSS表示实际驻留内存,是进程使用的物理内存部分,不包括交换空间。- 内存值以kB为单位,示例中转换为MB以便于阅读。
运行此代码需要Linux环境,并可能需要root权限以访问所有进程信息。输出示例如下:
PID: 1, Memory Usage: 8.50 MB
PID: 2, Memory Usage: 0.00 MB
...

