mirror of
https://github.com/shirou/gopsutil.git
synced 2025-04-24 13:48:56 +08:00
imeplements Process.Memory_Maps(). This is a function because map is very large.
This commit is contained in:
parent
79811544a4
commit
400054f2f0
@ -86,9 +86,11 @@ Current Status
|
||||
- terminal (linux)
|
||||
- nice (linux)
|
||||
- num_fds (linux)
|
||||
- num_threads (linux)
|
||||
- cpu_times (linux)
|
||||
- memory_info (linux)
|
||||
- memory_info_ex (linux)
|
||||
- Memory_maps() (linux) <- this is a function
|
||||
|
||||
- not yet
|
||||
|
||||
@ -109,7 +111,6 @@ Current Status
|
||||
- cpu_percent
|
||||
- cpu_affinity
|
||||
- memory_percent
|
||||
- memory_maps
|
||||
- children
|
||||
- open_files
|
||||
- connections
|
||||
|
@ -46,13 +46,6 @@ type Memory_infoStat struct {
|
||||
VMS uint64 `json:"vms"` // bytes
|
||||
}
|
||||
|
||||
type Memory_mapsStat struct {
|
||||
Path string `json:"path"`
|
||||
RSS int32 `json:"rss"`
|
||||
Anonymous int32 `json:"anonymous"`
|
||||
Swap int32 `json:"swap"`
|
||||
}
|
||||
|
||||
type RlimitStat struct {
|
||||
Resource int32 `json:"resource"`
|
||||
Soft int32 `json:"soft"`
|
||||
|
@ -9,6 +9,13 @@ import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// Memory_info_ex is different between OSes
|
||||
type Memory_info_exStat struct {
|
||||
}
|
||||
|
||||
type Memory_mapsStat struct {
|
||||
}
|
||||
|
||||
func Pids() ([]int32, error) {
|
||||
ret := make([]int32, 0)
|
||||
procs, err := processes()
|
||||
@ -23,6 +30,11 @@ func Pids() ([]int32, error) {
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (p *Process) Memory_Maps() (*[]Memory_mapsStat, error) {
|
||||
ret := make([]Memory_mapsStat, 0)
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func copy_params(k *Kinfo_proc, p *Process) error {
|
||||
p.Exe = byteToString(k.Ki_comm[:])
|
||||
p.Ppid = k.Ki_ppid
|
||||
|
@ -27,6 +27,20 @@ type Memory_info_exStat struct {
|
||||
Dirty uint64 `json:"dirty"` // bytes
|
||||
}
|
||||
|
||||
type Memory_mapsStat struct {
|
||||
Path string `json:"path"`
|
||||
Rss uint64 `json:"rss"`
|
||||
Size uint64 `json:"size"`
|
||||
Pss uint64 `json:"pss"`
|
||||
Shared_clean uint64 `json:"shared_clean"`
|
||||
Shared_dirty uint64 `json:"shared_dirty"`
|
||||
Private_clean uint64 `json:"private_clean"`
|
||||
Private_dirty uint64 `json:"private_dirty"`
|
||||
Referenced uint64 `json:"referenced"`
|
||||
Anonymous uint64 `json:"anonymous"`
|
||||
Swap uint64 `json:"swap"`
|
||||
}
|
||||
|
||||
type fillFunc func(pid int32, p *Process) error
|
||||
|
||||
func NewProcess(pid int32) (*Process, error) {
|
||||
@ -51,6 +65,73 @@ func NewProcess(pid int32) (*Process, error) {
|
||||
return p, nil
|
||||
}
|
||||
|
||||
// Get memory maps from /proc/(pid)/smaps
|
||||
// This is a function. Because Memory map information is very big.
|
||||
func (p *Process) Memory_Maps() (*[]Memory_mapsStat, error) {
|
||||
pid := p.Pid
|
||||
ret := make([]Memory_mapsStat, 0)
|
||||
smapsPath := filepath.Join("/", "proc", strconv.Itoa(int(pid)), "smaps")
|
||||
contents, err := ioutil.ReadFile(smapsPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
lines := strings.Split(string(contents), "\n")
|
||||
|
||||
// function of parsing a block
|
||||
get_block := func(first_line []string, block []string) Memory_mapsStat {
|
||||
m := Memory_mapsStat{}
|
||||
m.Path = first_line[len(first_line)-1]
|
||||
|
||||
for _, line := range block {
|
||||
field := strings.Split(line, ":")
|
||||
if len(field) < 2 {
|
||||
continue
|
||||
}
|
||||
v := strings.Trim(field[1], " kB") // remove last "kB"
|
||||
switch field[0] {
|
||||
case "Size":
|
||||
m.Size = parseUint64(v)
|
||||
case "Rss":
|
||||
m.Rss = parseUint64(v)
|
||||
case "Pss":
|
||||
m.Pss = parseUint64(v)
|
||||
case "Shared_Clean":
|
||||
m.Shared_clean = parseUint64(v)
|
||||
case "Shared_Dirty":
|
||||
m.Shared_dirty = parseUint64(v)
|
||||
case "Private_Clean":
|
||||
m.Private_clean = parseUint64(v)
|
||||
case "Private_Dirty":
|
||||
m.Private_dirty = parseUint64(v)
|
||||
case "Referenced":
|
||||
m.Referenced = parseUint64(v)
|
||||
case "Anonymous":
|
||||
m.Anonymous = parseUint64(v)
|
||||
case "Swap":
|
||||
m.Swap = parseUint64(v)
|
||||
}
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
blocks := make([]string, 16)
|
||||
for _, line := range lines {
|
||||
field := strings.Split(line, " ")
|
||||
if strings.HasSuffix(field[0], ":") == false {
|
||||
// new block section
|
||||
if len(blocks) > 0 {
|
||||
ret = append(ret, get_block(field, blocks))
|
||||
}
|
||||
// starts new block
|
||||
blocks = make([]string, 16)
|
||||
} else {
|
||||
blocks = append(blocks, line)
|
||||
}
|
||||
}
|
||||
|
||||
return &ret, nil
|
||||
}
|
||||
|
||||
// Parse to int32 without error
|
||||
func parseInt32(val string) int32 {
|
||||
vv, _ := strconv.ParseInt(val, 10, 32)
|
||||
@ -146,7 +227,7 @@ func fillFromStatm(pid int32, p *Process) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// get various status from /proc/(pid)/status
|
||||
// Get various status from /proc/(pid)/status
|
||||
func fillFromStatus(pid int32, p *Process) error {
|
||||
statPath := filepath.Join("/", "proc", strconv.Itoa(int(pid)), "status")
|
||||
contents, err := ioutil.ReadFile(statPath)
|
||||
|
@ -34,7 +34,7 @@ func Test_Pid_exists(t *testing.T) {
|
||||
}
|
||||
|
||||
func Test_NewProcess(t *testing.T) {
|
||||
check_pid := 1
|
||||
check_pid := 19472
|
||||
if runtime.GOOS == "windows" {
|
||||
check_pid = 0
|
||||
}
|
||||
@ -47,3 +47,20 @@ func Test_NewProcess(t *testing.T) {
|
||||
d, _ := json.Marshal(ret)
|
||||
fmt.Println(string(d))
|
||||
}
|
||||
|
||||
func Test_Process_memory_maps(t *testing.T) {
|
||||
check_pid := 19472
|
||||
if runtime.GOOS == "windows" {
|
||||
check_pid = 0
|
||||
}
|
||||
ret, err := NewProcess(int32(check_pid))
|
||||
|
||||
mmaps, err := ret.Memory_Maps()
|
||||
if err != nil {
|
||||
t.Errorf("memory map get error %v", err)
|
||||
}
|
||||
for _, m := range *mmaps {
|
||||
fmt.Println(m)
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -50,6 +50,13 @@ type SYSTEM_PROCESS_INFORMATION struct {
|
||||
}
|
||||
*/
|
||||
|
||||
// Memory_info_ex is different between OSes
|
||||
type Memory_info_exStat struct {
|
||||
}
|
||||
|
||||
type Memory_mapsStat struct {
|
||||
}
|
||||
|
||||
func Pids() ([]int32, error) {
|
||||
ret := make([]int32, 0)
|
||||
|
||||
@ -64,6 +71,11 @@ func Pids() ([]int32, error) {
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (p *Process) Memory_Maps() (*[]Memory_mapsStat, error) {
|
||||
ret := make([]Memory_mapsStat, 0)
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func NewProcess(pid int32) (*Process, error) {
|
||||
p := &Process{Pid: pid}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user