Golang os/exec,实时内存使用情况

huangapple go评论175阅读模式
英文:

Golang os/exec, realtime memory usage

问题

我正在使用Linux、Go和os/exec来运行一些命令。
我想知道一个进程的实时内存使用情况。这意味着我可以在启动进程后随时询问内存使用情况,而不仅仅是在它运行后。
(这就是为什么https://stackoverflow.com/questions/27625787/measuring-memory-usage-of-executable-run-using-golang中的答案对我来说不是一个选择)

例如:

  1. cmd := exec.Command(...)
  2. cmd.Start()
  3. //...
  4. if cmd.Memory() > 50 {
  5. fmt.Println("哦,天哪,这个进程对内存的需求很大!")
  6. }

我不需要非常精确的值,但如果误差范围低于10兆字节,那就太好了。

有没有一种Go的方法可以做到这一点,还是我需要某种命令行的技巧?

英文:

I'm using Linux, go, and os/exec to run some commands.
I want to know a process' realtime memory usage. That means that I can ask for memory usage anytime after I start the process, not just after it ran.

(That's why the answer in https://stackoverflow.com/questions/27625787/measuring-memory-usage-of-executable-run-using-golang is not an option for me)

For example:

  1. cmd := exec.Command(...)
  2. cmd.Start()
  3. //...
  4. if cmd.Memory()>50 {
  5. fmt.Println("Oh my god, this process is hungry for memory!")
  6. }

I don't need very precise value, but it would be great if it's error range is lower than, say, 10 megabytes.

Is there a go way to do that or I need some kind of command line trick?

答案1

得分: 7

这是我在Linux上使用的代码:

  1. func calculateMemory(pid int) (uint64, error) {
  2. f, err := os.Open(fmt.Sprintf("/proc/%d/smaps", pid))
  3. if err != nil {
  4. return 0, err
  5. }
  6. defer f.Close()
  7. res := uint64(0)
  8. pfx := []byte("Pss:")
  9. r := bufio.NewScanner(f)
  10. for r.Scan() {
  11. line := r.Bytes()
  12. if bytes.HasPrefix(line, pfx) {
  13. var size uint64
  14. _, err := fmt.Sscanf(string(line[4:]), "%d", &size)
  15. if err != nil {
  16. return 0, err
  17. }
  18. res += size
  19. }
  20. }
  21. if err := r.Err(); err != nil {
  22. return 0, err
  23. }
  24. return res, nil
  25. }

这个函数返回给定PID的PSS(比例设置大小),以KB为单位。如果你刚刚启动了进程,你应该有权限访问相应的/proc文件。

在内核版本3.0.13上进行了测试。

英文:

Here is what I use on Linux:

  1. func calculateMemory(pid int) (uint64, error) {
  2. f, err := os.Open(fmt.Sprintf("/proc/%d/smaps", pid))
  3. if err != nil {
  4. return 0, err
  5. }
  6. defer f.Close()
  7. res := uint64(0)
  8. pfx := []byte("Pss:")
  9. r := bufio.NewScanner(f)
  10. for r.Scan() {
  11. line := r.Bytes()
  12. if bytes.HasPrefix(line, pfx) {
  13. var size uint64
  14. _, err := fmt.Sscanf(string(line[4:]), "%d", &size)
  15. if err != nil {
  16. return 0, err
  17. }
  18. res += size
  19. }
  20. }
  21. if err := r.Err(); err != nil {
  22. return 0, err
  23. }
  24. return res, nil
  25. }

This function returns the PSS (Proportional Set Size) for a given PID, expressed in KB. If you have just started the process, you should have the rights to access the corresponding /proc file.

Tested with kernel 3.0.13.

huangapple
  • 本文由 发表于 2015年8月7日 22:12:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/31879817.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定