英文:
how to get golang rss from runtime.MemStats
问题
我从runtime.MemStats中读取了(go)mem信息,但找不到rss值。我使用m.HeapSys-m.HeapReleased来计算,但发现该值与rss非常不相似。我还使用其他工具(github.com/shirou/gopsutil/process)转储了Rss,我想知道如何通过memstats获取rss,以及为什么m.HeapSys-m.HeapReleased和m.Sys与rss不相等,值如此不同?
package main
import (
"fmt"
"github.com/gin-gonic/gin"
"io/ioutil"
"log"
"os"
"github.com/dustin/go-humanize"
"github.com/prometheus/client_golang/prometheus/promhttp"
"github.com/shirou/gopsutil/process"
"runtime"
"strconv"
"strings"
"syscall"
"time"
)
var pageSize = syscall.Getpagesize()
// rss返回当前进程的常驻集大小,单位为MiB
func rss() int {
data, err := ioutil.ReadFile("/proc/self/stat")
if err != nil {
log.Fatal(err)
}
fs := strings.Fields(string(data))
rss, err := strconv.ParseInt(fs[23], 10, 64)
if err != nil {
log.Fatal(err)
}
return int(uintptr(rss) * uintptr(pageSize) / (1 << 20)) // MiB
}
func getPs(pid int) {
ps, _ := process.Processes()
for _, p := range ps {
if p.Pid == int32(pid) {
mem, _ := p.MemoryInfo()
fmt.Printf("通过进程获取的rss:%s\n", humanize.Bytes(mem.RSS))
}
}
}
func main() {
pid := os.Getpid()
go func() {
for {
var m runtime.MemStats
runtime.ReadMemStats(&m)
fmt.Printf("rss:%s\n", humanize.Bytes(m.HeapSys-m.HeapReleased))
getPs(pid)
fmt.Println("通过文件获取的rss:MB", rss())
fmt.Println()
time.Sleep(10 * time.Second)
}
}()
r := gin.Default()
r.GET("/metrics", gin.WrapH(promhttp.Handler()))
log.Fatal(r.Run())
}
输出如下:
rss:6.6 MB
通过进程获取的rss:18 MB
通过文件获取的rss:MB 17
英文:
i read the (go)mem info from runtime.MemStats, but cant found rss value, i use m.HeapSys-m.HeapReleased, but found the value is very not like rss ,also i dump the Rss by other tool(github.com/shirou/gopsutil/process), i want to know how to get the rss by memstats, and why m.HeapSys-m.HeapReleased, and m.Sys not equal the rss, so different the value ?
package main
import (
"fmt"
"github.com/gin-gonic/gin"
"io/ioutil"
"log"
"os"
"github.com/dustin/go-humanize"
"github.com/prometheus/client_golang/prometheus/promhttp"
"github.com/shirou/gopsutil/process"
"runtime"
"strconv"
"strings"
"syscall"
"time"
)
var pageSize = syscall.Getpagesize()
// rss returns the resident set size of the current process, unit in MiB
func rss() int {
data, err := ioutil.ReadFile("/proc/self/stat")
if err != nil {
log.Fatal(err)
}
fs := strings.Fields(string(data))
rss, err := strconv.ParseInt(fs[23], 10, 64)
if err != nil {
log.Fatal(err)
}
return int(uintptr(rss) * uintptr(pageSize) / (1 << 20)) // MiB
}
func getPs(pid int) {
ps, _ := process.Processes()
for _, p := range ps {
if p.Pid == int32(pid) {
mem, _ := p.MemoryInfo()
fmt.Printf("get by process rss:%s\n", humanize.Bytes(mem.RSS))
}
}
}
func main() {
pid := os.Getpid()
go func() {
for {
var m runtime.MemStats
runtime.ReadMemStats(&m)
fmt.Printf("rss:%s\n", humanize.Bytes(m.HeapSys-m.HeapReleased))
getPs(pid)
fmt.Println("rss by file:MB", rss())
fmt.Println()
time.Sleep(10 * time.Second)
}
}()
r := gin.Default()
r.GET("/metrics", gin.WrapH(promhttp.Handler()))
log.Fatal(r.Run())
}
*/
output like this
rss:6.6 MB
get by process rss:18 MB
rss by file:MB 17
答案1
得分: 1
最接近的值是memstats.Sys ~= RSS,但它们并不完全相等,因为RSS包含了一些其他的内容,比如共享库等,并且Go内存也可以来自虚拟内存,而不是全部来自RSS。
英文:
The closest value is memstats.Sys ~= RSS, but they are not absolute equal , beacuse the rss contain some other like share lib,equal , and the
go memory alose can be from virtual memory,not all from rss
答案2
得分: 0
你不能从runtime.MemStats中获取golang的rss信息。
m.HeapSys-m.HeapReleased和m.Sys与rss不相等,因为rss是一个完全不同的度量指标。
英文:
> [H]ow to get golang rss from runtime.MemStats [?]
You cannot. runtime.Memstats doesn't provide that information.
> why m.HeapSys-m.HeapReleased, and m.Sys not equal the rss [?]
Because RSS is a completely different metric.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论