从/proc/[pid]/目录下获取进程的详细信息

 2017年5月30日 22:28   Nick王   运维    1 评论   289 浏览 


官方man 文档地址:https://www.kernel.org/doc/man-pages/

官方链接:http://man7.org/linux/man-pages/man5/proc.5.html

相关 http://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt

本文是在CentOS 7.2上操作的

首先获取某个进程的PID我这里获取mysql

# ps -ef|grep mysqld|grep -v grep|awk '{if($3!=1){print $2}}'
14915


接下来进入到/proc/${pid}目录下

# cd /proc/14915


小提示:

/proc/self/ 中的self表示的是当前进程。

进程基本状态相关

获取进程名

通过文件comm获取

# cat /proc/14915/comm
mysqld


在CentOS 6.x的系统中是没有这个文件的,可以通过文件status获取

# grep "Name" /proc/14915/status|awk '{print $2}'
mysqld


通过ps命令获取

# ps -p 14915 -o comm|tail -n 1
mysqld


获取进程完整的命令行启动参数

通过文件cmdline文件获取

# cat /proc/14915/cmdline
/usr/local/mysql/bin/mysqld--basedir=/usr/local/mysql--datadir=/var/lib/mysql/data--plugin-dir=/usr/local/mysql/lib/plugin--user=mysql--log-error=/var/lib/mysql/log/error.log--pid-file=/var/lib/mysql/data/localhost.localdomain.pid--socket=/var/run/mysqld/mysql.sock--port=3306


通过ps命令获取

# ps -p 14915 -o args|tail -n 1
/usr/local/mysql/bin/mysqld --basedir=/usr/local/mysql --datadir=/var/lib/mysql/data --plugin-dir=/usr/local/mysql/lib/plugin --user=mysql --log-error=/var/lib/mysql/log/error.log --pid-file=/var/lib/mysql/data/localhost.localdomain.pid --socket=/var/run/mysqld/mysql.sock --port=3306


获取启动(或者说执行)进程的程序的路径

通过软链接exe可以获取到

# ll /proc/14915/exe
lrwxrwxrwx 1 root root 0 Apr 11 10:49 /proc/14915/exe -> /usr/local/mysql/bin/mysqld

也就是说14915这个进程是由/usr/local/mysql/bin/mysqld这个程序启动的。


获取进程启动时所在的工作路径

通过软链接cwd可以获取到

# ll /proc/14915/cwd
lrwxrwxrwx 1 root root 0 Apr 11 10:49 /proc/14915/cwd -> /var/lib/mysql/data

也就是说启动14915这个进程的时候,所在的工作目录是/var/lib/mysql/data,如果是在其他目录启动的那么就是其他路径,这个不一定。


获取进程启动时所使用的环境变量

通过文件environ获取

# cat /proc/14915/environ 
XDG_SESSION_ID=2HOSTNAME=localhost.localdomainSHELL=/bin/bashTERM=xtermHISTSIZE=1000SSH_CLIENT=10.111.23.176 60224 22SSH_TTY=/dev/pts/0USER=rootLS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=01;05;37;41:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=01;36:*.au=01;36:*.flac=01;36:*.mid=01;36:*.midi=01;36:*.mka=01;36:*.mp3=01;36:*.mpc=01;36:*.ogg=01;36:*.ra=01;36:*.wav=01;36:*.axa=01;36:*.oga=01;36:*.spx=01;36:*.xspf=01;36:PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/mysql/binMAIL=/var/spool/mail/rootPWD=/usr/local/mysqlLANG=en_US.UTF-8HISTCONTROL=ignoredupsHOME=/rootSHLVL=4LOGNAME=rootSSH_CONNECTION=10.111.23.176 60224 10.111.32.82 22LESSOPEN=||/usr/bin/lesspipe.sh %sMYSQL_HOME=/usr/local/mysqlXDG_RUNTIME_DIR=/run/user/0_=/bin/nohup


使用cat -A xxx命令可以看到分隔符,这里使用tr命令将默认的\000替换成\n

# cat /proc/14915/environ | tr '\000' '\n' 
XDG_SESSION_ID=2 
HOSTNAME=localhost.localdomain 
SHELL=/bin/bash 
TERM=xterm 
HISTSIZE=1000 
SSH_CLIENT=10.111.23.176 60224 22 
SSH_TTY=/dev/pts/0 
USER=root 
LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=01;05;37;41:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=01;36:*.au=01;36:*.flac=01;36:*.mid=01;36:*.midi=01;36:*.mka=01;36:*.mp3=01;36:*.mpc=01;36:*.ogg=01;36:*.ra=01;36:*.wav=01;36:*.axa=01;36:*.oga=01;36:*.spx=01;36:*.xspf=01;36: 
PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/mysql/bin 
MAIL=/var/spool/mail/root 
PWD=/usr/local/mysql
LANG=en_US.UTF-8 
HISTCONTROL=ignoredups 
HOME=/root 
SHLVL=4 
LOGNAME=root 
SSH_CONNECTION=10.111.23.176 60224 10.111.32.82 22 
LESSOPEN=||/usr/bin/lesspipe.sh %s 
MYSQL_HOME=/usr/local/mysql 
XDG_RUNTIME_DIR=/run/user/0 
_=/bin/nohup


获取进程的资源限制

通过文件limits获取

# cat /proc/14915/limits
Limit                     Soft Limit           Hard Limit           Units
Max cpu time              unlimited            unlimited            seconds
Max file size             unlimited            unlimited            bytes
Max data size             unlimited            unlimited            bytes
Max stack size            8388608              unlimited            bytes
Max core file size        0                    unlimited            bytes
Max resident set          unlimited            unlimited            bytes
Max processes             39235                39235                processes
Max open files            5010                 5010                 files
Max locked memory         65536                65536                bytes
Max address space         unlimited            unlimited            bytes
Max file locks            unlimited            unlimited            locks
Max pending signals       39235                39235                signals
Max msgqueue size         819200               819200               bytes
Max nice priority         0                    0
Max realtime priority     0                    0
Max realtime timeout      unlimited            unlimited            us

进程的内存相关

通过文件statm获取

# cat /proc/14915/statm
2617218 261557 3009 5816 0 2604257 0

解释:

  • size:(1) total program size(same as VmSize in /proc/[pid]/status) 等同于VmSize/Page_Size

  • resident:(2) resident set size(same as VmRSS in /proc/[pid]/status) 常驻内存大小 但也也是Page_size

  • shared:(3) number of resident shared pages (i.e., backed by a file)(same as RssFile+RssShmem in /proc/[pid]/status) 共享内存

  • text:(4) text (code) 代码占用内存

  • lib:(5) library (unused since Linux 2.6; always 0) 库文件占用内存

  • data:(6) data + stack 数据占用内存

  • dt:(7) dirty pages (unused since Linux 2.6; always 0) 脏页占用内存


关于size(虚拟内存地址空间)

虚拟内存地址空间,包含程序代码文本,数据和stack空间,并不是真正使用的大小。在64位操作系统上,可用的最大虚拟地址空间有16EB,即大概180亿GB。

提示:相当于top命令中的VIRT选项

使用ps命令获取size

# ps -p 14915 -o sz|tail -n 1
2617218  注意这里获取到的是page 数量


关于ps命令中sz的解释(可以通过man ps查看):

size in physical pages of the core image of the process. This includes text, data, and stack space. Device mappings are currently excluded; this is subject to change. See vsz and rss.

ps命令的另一个获取指标

# ps -p 14915 -o vsz | tail -n 1
10468872  这里获取到的内存大小单位为KB


关于vsz的解释:

virtual memory size of the process in KiB (1024-byte units). Device mappings are currently excluded; this is subject to change. (alias vsize).

通过status文件中的VmSize获取:

# grep "VmSize" /proc/14915/status|awk '{print $2,$3}'
10468872 kB

# getconf PAGE_SIZE
4096

# echo $(($(grep "VmSize" /proc/14915/status|awk '{print $2}')/($(getconf PAGE_SIZE)/1024)))
2617218


关于resident(常驻的运行内存)

表示真实使用的除了swap之外的物理内存

提示: 相当于top命令中的RES选项

使用ps命令的rsz选项获取

# 获取rs内存大小
# ps -p 14915 -o rsz|tail -n 1
1046228

# 根据内存大小算出pages
# echo $(($(ps -p 14915 -o rsz|tail -n 1)/($(getconf PAGE_SIZE)/1024)))
261557

# statm文件中的rs
# cat /proc/14915/statm | awk '{print $2}'
261557


关于RSZ的解释:

resident set size, the non-swapped physical memory that a task has used (in kiloBytes).

通过文件status文件获取

# grep "VmRSS" /proc/14915/status|awk '{print $2,$3}'
1046228 kB


关于shared(常驻共享内存)

提示: 相当于top命令中的SHR选项

通过文件status文件获取

# cat /proc/14915/statm|awk '{print $3}'
3009

# egrep "RssFile|RssShmem" /proc/14915/status
RssFile:	   12036 kB
RssShmem:	       0 kB

# egrep "RssFile|RssShmem" /proc/14915/status | awk '{sum=sum+$2} END{print sum}'
12036

# echo $(($(egrep "RssFile|RssShmem" /proc/14915/status | awk '{sum=sum+$2} END{print sum}')/($(getconf PAGE_SIZE)/1024)))
3009


获取进程得内存映射(内存布局,内存消耗,进程的各个组成部分(代码段/数据段/动态加载的SO)的地址)

通过文件smaps获取

# sed -n '/VmFlags/{n;p}' smaps
01cb7000-01e57000 rw-p 016b7000 fd:00 100900683                          /usr/local/mysql/bin/mysqld
01e57000-01f12000 rw-p 00000000 00:00 
00256e000-10595000 rw-p 00000000 00:00 0                                  [heap]
7fdab4000000-7fdab422d000 rw-p 00000000 00:00 0
……太多了……


通过文件maps获取

# cat /proc/14915/maps
00400000-01ab8000 r-xp 00000000 fd:00 100900683                          /usr/local/mysql/bin/mysqld
01cb7000-01e57000 rw-p 016b7000 fd:00 100900683                          /usr/local/mysql/bin/mysqld
01e57000-01f12000 rw-p 00000000 00:00 
00256e000-10595000 rw-p 00000000 00:00 0                                  [heap]
7fdab4000000-7fdab422d000 rw-p 00000000 00:00 07fdab422d000-7fdab8000000 ---p 00000000 00:00 0
……太多了……


通过命令pmap获得如下信息

# pmap -p 1491514915:   /usr/local/mysql/bin/mysqld --basedir=/usr/local/mysql --datadir=/var/lib/mysql/data --plugin-dir=/usr/local/mysql/lib/plugin --user=mysql --log-error=/var/lib/mysql/log/error.log --pid-file=/var/lib/mysql/data/localhost.localdomain.pid --socket=/var/run/mysqld/mysql.sock --port=3306
0000000000400000  23264K r-x-- /usr/local/mysql/bin/mysqld
0000000001cb7000   1664K rw--- /usr/local/mysql/bin/mysqld
0000000001e57000    748K rw---   [ anon ]
000000000256e000 229532K rw---   [ anon ]
……太多了……

smaps指的是动态当前的消耗量(可以看到内存的具体消耗)

maps更像是一个静态的内存布局


高级的进程的状态

提示:使用htop工具可以完整的获取

通过文件stat可以获取到

# cat /proc/14915/stat
14915 (mysqld) S 13939 13902 10290 0 -1 1077944576 110944 0 0 0 49700 2055 0 0 20 0 33 0 795194 10720124928 261557 18446744073709551615 4194304 28014288 140733631974000 140733631971328 140587786284541 0 540679 12294 1768 184467440737095516150 0 17 1 0 0 43 0 0 30111440 31811304 39247872 140733631977281 140733631977566 140733631977566 140733631979484 0

字段说明:

  1. pid:整形数据,表示进程ID

  2. comm:字符串类型,表示进程文件名

  3. state:进程状态,R(运行状态)S(休眠,可中断的等待)D(等待不可间断的磁盘休眠)Z(僵尸)

  4. ppid:整形数据,表示父进程ID

  5. pgrp: 整形数据,进程的进程组ID

  6. session: 整形数据,进程所在的的session组ID

  7. tty_nr:整形数据,进程的控制终端的tty的设备号

  8. tpgid:整形数据,终端的进程组号,当前运行在该任务所在终端的前台任务(包括shell 应用程序)的PID

  9. flags:无符号整形,进程的内核标志位

  10. minflt:该任务不需要从硬盘拷数据而发生的缺页(次缺页)的中断的数目

  11. cminflt:累计的该任务的所有的waited-for进程曾经发生的次缺页的次数目

  12. majflt:该任务需要从硬盘拷数据而发生的缺页(主缺页)的次数,主缺页数,需要触发磁盘I/O

  13. cmajflt:累计的该任务的所有的waited-for进程曾经发生的主缺页的次数目

  14. utime:该任务在用户态运行的时间,单位为jiffies(可以转换位秒)在小于2.6的内核上,在大于2.6的内核上单位为clock ticks

  15. stime:该任务在核心态运行的时间,单位为jiffies(可以转换位秒)在小于2.6的内核上,在大于2.6的内核上单位为clock ticks

  16. cutime:累计的该任务的所有的waited-for进程曾经在用户态运行的时间,单位同上(该进程的等待子线程处于用户态的的时间)

  17. cstime:累计的该任务的所有的waited-for进程曾经在核心态运行的时间,单位同上(该进程的等待子线程处于核心态的的时间)

  18. priority: 任务的动态优先级

  19. nice:任务的静态优先级

  20. num_threads:该任务所在的线程组里线程的个数

  21. itrealvalue:由于计时间隔导致的下一个 SIGALRM 发送进程的时延,已经废弃

  22. starttime:该任务启动的时间,单位同上

  23. vsize:该任务的虚拟地址空间大小,单位为B

  24. rss:该任务当前驻留物理地址空间的大小,单位为page

  25. rsslim:该任务能驻留物理地址空间的最大值

  26. startcode: 该任务在虚拟地址空间的代码段的起始地址

  27. endcode: 该任务在虚拟地址空间的代码段的结束地址

  28. startstack:该任务在虚拟地址空间的栈的结束地址

  29. kstkesp:当前访问的栈指针ESP的值

  30. kstkeip:当前指令指针(EIP)的值

  31. signal:被挂起信号的二进制位图,已被废弃,当前的信号值见/proc/[pid]/status

  32. blocked:被阻塞信号的位图,被废

  33. sigignore:被忽视的信号位图,被废

  34. sigcatch:被获取的信号位图,被废

  35. wchan:进程正在等待的“channel”,当进程正在睡眠时,该字段给出了进程的调用点

  36. nswap: 交换得到页数,一直无效

  37. cnswap:所有子进程被swapped的页数的和,无效

  38. exit_signal:当本进程“死去”时发给父进程的信号

  39. processor:运行在哪个CPU上

  40. rt_priority:实时进程的相对优先级别

  41. policy:进程的调度策略,0=非实时进程,1=FIFO实时进程;2=RR实时进程

  42. delayacct_blkio_ticks:

  43. guest_time:进程用于用户操作系统的时间,单位是clock tick。(和/proc/stat中cpu部分的倒数第二个字段对应)

  44. cguest_time:进程的子线程用于用户操作系统的时间

  45. start_data:进程初始化和非初始化的数据的存放起始地址

  46. end_data:进程初始化和非初始化的数据的存放结束地址

  47. start_brk:可以通过brk()函数扩展heap空间的起始地址

  48. arg_start:命令行参数表argv存放的起始地址

  49. arg_end:命令行参数表argv存放的终止地址

  50. env_start:存放进程执行环境变量的起始地址

  51. env_end:存放进程执行环境变量的终止地址

  52. exit_code:进程的退出码。

在3.10的内核中有52个值

# cat /proc/14915/stat|awk '{print NF}'
52

# uname -r
3.10.0-514.10.2.el7.x86_64


案例1:获取进程运行在哪个CPU上

# ps -p 14915 -o psr |tail -n 1
  1
# cat /proc/14915/stat | awk '{print $39}'
1


案例2:获取进程的线程数

# ls /proc/14915/task/ | wc -l33
# grep "Threads" /proc/14915/status|awk '{print $2}'
33
# cat /proc/14915/stat | awk '{print $20}'
33
# ps -p 14915 -o thcount| tail -n 1
   33


案例3:获取进程的虚拟内存空间大小

# grep "VmSize" /proc/14915/status | awk '{print $2}'
10468872

# ps -p 14915 -o vsz | tail -n 1
10468872

# echo $(($(cat /proc/14915/stat | awk '{print $23}')/1024))
10468872


案例4:获取进程的常驻内存大小

# ps -p 14915 -o rsz | tail -n 1
1046228

# echo $(($(cat /proc/14915/stat | awk '{print $24}')*4))
1046228

# grep "VmRSS" /proc/14915/status | awk '{print $2}'
1046228


案例5:获取任务的详细启动时间

注意:在2.6内核之前和之后的单位是不同的

在2.6之前的单位是jiffies

在2.6之后的单位是clock ticks

clock_tick在绝大多数机器上是1秒/100,可以通过sysconf(_SC_CLK_TCK)函数来获得clock_tick

关于jiffies单位,通过cat /boot/config-`uname -r` | grep '^CONFIG_HZ='命令获取当前机器的HZ

# 通过使用ps命令获取进程的启动时间
# ps -p 14915 -o lstart|tail -n 1
Thu Mar 30 20:21:40 2017

# 通过Python脚本计算进程的启动时间
# python /root/calc_stime.py $(cat /proc/14915/stat|awk '{print $22}')
Thu Mar 30 20:21:40 2017
1102465.16267

# Python脚本内容如下
# cat /root/calc_stime.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from __future__ import division
import os
import sys
import time

# 获取clock ticks
sc_clk_tck = os.sysconf_names.get('SC_CLK_TCK')
clk_tck = os.sysconf(sc_clk_tck)

# 获取系统启动时间
with open('/proc/stat') as fn:    
    for line in fn.xreadlines():        
        if line.startswith('btime'):
            btime = line.split()[1]

# 计算
p_time = (int(sys.argv[1]) / clk_tck) + int(btime)
print(time.ctime(p_time))
print(time.time() - p_time)


案例6: 获取进程的运行时间

# ps -p 14915 -o bsdtime|tail -n 1
  9:02
  
# python /root/calc_rtime.py $(cat stat|awk '{sum=$14+$15+$16+$17} END{print sum}')
9.0425

# 脚本内容如下
# cat /root/calc_rtime.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from __future__ import division
import os
import sys
import time

# 获取clock ticks
sc_clk_tck = os.sysconf_names.get('SC_CLK_TCK')
clk_tck = os.sysconf(sc_clk_tck)

# 计算

p_time = (int(sys.argv[1]) / clk_tck) / 60
print(p_time)


获取进程的信息以更友好的格式

相当于statm文件和stat文件的内容的结合,通过status获取

# cat /proc/14915/status
Name:	mysqld
State:	S (sleeping)
Tgid:	14915  线程组ID
Ngid:	0    NUMA组ID
Pid:	14915PPid:	13939TracerPid:	0  追踪进程PID
Uid:	997	997	997	997 分别表示Real, effective, saved set, and filesystem UIDs
Gid:	995	995	995	995
FDSize:	256 当前分配的文件描述符
Groups:	995  启动这个进程的用户所在的组列表
VmPeak:	11019536 kB 申请的内存地址空间存的峰值
VmSize:	10468872 kB 虚拟地址空间的大小
VmLck:	       0 kB 进程已经锁住的物理内存的大小
VmPin:	       0 kB  固定内存大小
VmHWM:	 1053700 kB 常驻内存峰值
VmRSS:	 1046228 kB 程序现在使用的物理内存
RssAnon:	 1034192 kB 常驻匿名内存大小
RssFile:	   12036 kB 常驻文件映射大小
RssShmem:	       0 kB 常驻共享内存大小
VmData:	10416892 kB  虚拟内存地址空间内数据段大小
VmStk:	     136 kB 虚拟内存地址空间内stack(堆栈)段大小
VmExe:	   23264 kB 虚拟内存地址空间text段大小
VmLib:	    4140 kB 共享库代码大小
VmPTE:	    2284 kB  page表条目大小
VmSwap:	       0 kB  进程占用swap大小
Threads:	33  子进程数量
SigQ:	0/39235
SigPnd:	0000000000000000
ShdPnd:	0000000000000000
SigBlk:	0000000000084007
SigIgn:	0000000000003006
SigCgt:	00000001800006e8
CapInh:	0000000000000000
CapPrm:	0000000000000000
CapEff:	0000000000000000
CapBnd:	0000001fffffffff
CapAmb:	0000000000000000
Seccomp:	0Cpus_allowed:	7fff 该进程可以使用CPU的亲和性掩码
Cpus_allowed_list:	0-14 
Mems_allowed:	00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000001
Mems_allowed_list:	0voluntary_ctxt_switches:	303 进程主动切换的次数
nonvoluntary_ctxt_switches:	14 进程被动切换的次数


获取进程得所有子线程

通过task目录获取

# ls /proc/14915/task/14915  
14919  14921  14923  14925  14927  14929  14931  14936  14938  14940  14942  14944  14946  14948  15076  32059
14916  14920  14922  14924  14926  14928  14930  14932  14937  14939  14941  14943  14945  14947  14950  32008


进程相关得网络信息

/proc/[pid]/net的内容跟/proc/net的内容是一样的。

这个文件的各个文件包含了有关网络的相关信息。

注意:事实上无法获取进程相关的网络信息。

获取ARP表

通过文件arp获取,基本和arp命令的结果是一样的

# cat /proc/net/arp
IP address       HW type     Flags       HW address            Mask     Device
10.111.32.4      0x1         0x2         30:d1:7e:ec:9a:64     *        eth0
10.111.32.176    0x1         0x2         2e:ec:b4:cb:50:b5     *        eth0
10.111.32.2      0x1         0x2         30:d1:7e:b4:d9:2d     *        eth0
10.111.32.1      0x1         0x2         10:47:80:28:02:e0     *        eth0
10.111.32.3      0x1         0x2         30:d1:7e:ec:9a:56     *        eth0


解释:

  1. IP address:是主机的IPv4地址

  2. HW type:是硬件类型(这里是16进制表示Ethernet)

  3. Flags:内部的ARP结构标志位

  4. HW address:网卡地址

  5. Mask:

  6. Device:是设备名

使用arp命令获取,如下

# arp -en
Address                  HWtype  HWaddress           Flags Mask            Iface
10.111.32.4              ether   30:d1:7e:ec:9a:64   C                     eth0
10.111.32.176            ether   2e:ec:b4:cb:50:b5   C                     eth0
10.111.32.2              ether   30:d1:7e:b4:d9:2d   C                     eth0
10.111.32.1              ether   10:47:80:28:02:e0   C                     eth0
10.111.32.3              ether   30:d1:7e:ec:9a:56   C                     eth0


获取网络设备的实时数据

通过文件dev获取,命令ifconfig就是通过这个文件获取的网络设备状态

# cat /proc/net/dev
Inter-|   Receive                                                |  Transmit
 face |bytes    packets errs drop fifo frame compressed multicast|bytes    packets errs drop fifo colls carrier compressed
  eth0: 1052365957 5309884    0   24    0     0          0         0 53202863  380896    0    0    0     0       0   0
  eth1:       0       0    0    0    0     0          0         0        0       0    0    0    0     0       00
    lo:  382493     435    0    0    0     0          0         0   382493     435    0    0    0     0       00


该文件内容很直观,分两个区域,左边是收包信息,右边是发包信息,接下来每个网卡分两行列举信息。

ifconfig命令的执行结果如下

# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.111.32.82  netmask 255.255.255.0  broadcast 10.111.32.255
        inet6 fe80::cdf8:22dc:4bc5:9b28  prefixlen 64  scopeid 0x20<link>
        ether fa:94:51:97:64:8a  txqueuelen 1000  (Ethernet)
        RX packets 5315088  bytes 1052948134 (1004.1 MiB)
        RX errors 0  dropped 24  overruns 0  frame 0
        TX packets 381586  bytes 53290822 (50.8 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
        
eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        ether ee:1f:f7:01:5a:66  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
        
lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1  (Local Loopback)
        RX packets 435  bytes 382493 (373.5 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 435  bytes 382493 (373.5 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0


使用netstat获取得结果如下:

# netstat -i
Kernel Interface table
Iface      MTU    RX-OK RX-ERR RX-DRP RX-OVR    TX-OK TX-ERR TX-DRP TX-OVR Flg
eth0      1500  5921412      0     24 0        406270      0      0      0 BMRU
eth1      1500        0      0      0 0             0      0      0      0 BMRU
lo       65536      435      0      0 0           435      0      0      0 LRU


获取TCP表,UDP表,UnixSocket表

通过文件tcp获取

# cat /proc/net/tcp
  sl  local_address rem_address   st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode   0: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 17122 1 ffff880036248000 100 0 0 10 0
   1: 0100007F:0019 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 17669 1 ffff880036228000 100 0 0 10 0
   2: 52206F0A:0016 B0176F0A:DBE0 01 00000034:00000000 01:00000019 00000000     0        0 1940295 4 ffff8801a86e1740 254 29 10 16
   3: 52206F0A:0016 B0176F0A:DFF8 01 00000000:00000000 02:00090EB8 00000000     0        0 1947093 2 ffff8801a86e0000 244 22 10 -1
   4: 52206F0A:0016 B0176F0A:DC96 01 00000000:00000000 02:00056EB8 00000000     0        0 1942071 2 ffff8801a86e07c0 244 22 10 -1

解释:

  1. sl:表示这个socket在内核中的哈希插槽

  2. local_address:表示本地地址和端口

  3. rem_address:表示远程地址和端口

  4. st:内部socket状态

  5. tx_queue:传出的数据队列

  6. rx_queue:传入的数据队列

  7. tr:内部信息,只对调试有用

  8. tm->when:同上,只对调试有用

  9. retrnsmt:同上,只对调试有用

  10. uid:创建这个socket的effective UID

  11. timeout:

  12. inode:inode节点

状态码对应关系如下: 状态码对应如下

  1. 00 “ERROR_STATUS”,

  2. 01 “TCP_ESTABLISHED”,

  3. 02 “TCP_SYN_SENT”,

  4. 03 “TCP_SYN_RECV”,

  5. 04 “TCP_FIN_WAIT1″,

  6. 05 “TCP_FIN_WAIT2″,

  7. 06 “TCP_TIME_WAIT”,

  8. 07 “TCP_CLOSE”,

  9. 08 “TCP_CLOSE_WAIT”,

  10. 09 “TCP_LAST_ACK”,

  11. 0A “TCP_LISTEN”,

  12. 0B “TCP_CLOSING”,

IP地址和端口的转换(文件里面看到的都是十六进制)

52206F0A:0016  冒号前面的表示IP地址,冒号后面的表示端口号,IP地址是8位,每2位表示一个16进制数值,从左到右依次为第四段,第三段,第二段,第一段

# python -c 'print ".".join([str(int("52206F0A", 16)/(256**i)%256) for i in range(4)])'
10.111.32.82

# echo $((0x0A))
10

# echo $((0x6F))
111


使用netstat命令的结果如下:

# netstat -tneo
Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       User       Inode      Timer
tcp        0     52 10.111.32.82:22         10.111.23.176:56288     ESTABLISHED 0          1940295    on (0.24/0/0)
tcp        0      0 10.111.32.82:22         10.111.23.176:57336     ESTABLISHED 0          1947093    keepalive (4737.66/0/0)
tcp        0      0 10.111.32.82:22         10.111.23.176:56470     ESTABLISHED 0          1942071    keepalive (2361.98/0/0)


通过文件udp获取

# cat /proc/net/udp
  sl  local_address rem_address   st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode ref pointer drops


使用netstat命令获取,如下

# netstat -uneoActive Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       User       Inode      Timer


通过文件unix获取

# cat /proc/net/unixNum       RefCount Protocol Flags    Type St Inode Path
ffff88026c7b8400: 00000002 00000000 00010000 0001 01 17736 private/relay
ffff8802703c6c00: 00000002 00000000 00010000 0001 01 17742 private/error
ffff8802722c7000: 00000002 00000000 00010000 0001 01 17745 private/retry
ffff88027275b000: 00000002 00000000 00010000 0001 01 11783 /run/systemd/private
ffff880284cefc00: 00000002 00000000 00010000 0001 01 11800 /run/lvm/lvmpolld.socket
ffff8802703c4c00: 00000002 00000000 00010000 0001 01 17687 private/rewrite
……太多了……


解释:

  1. Num:内核表中的插槽号

  2. RefCount:the number of users of the socket

  3. Protocol:

  4. Flags:

  5. Type:socket类型;0001表示SOCK_STREAM,0002表示SOCK_DGRAM,0005表示SOCK_SEQPACKET

  6. St:socket的内部状态

  7. Inode:

  8. Path:

使用netstat命令获取,如下

# netstat -x
Active UNIX domain sockets (w/o servers)
Proto RefCnt Flags       Type       State         I-Node   Path
unix  2      [ ]         DGRAM                    11849    /run/systemd/shutdownd
unix  2      [ ]         DGRAM                    7831     /run/systemd/notify
unix  2      [ ]         DGRAM                    7833     /run/systemd/cgroups-agent
unix  5      [ ]         DGRAM                    7851     /run/systemd/journal/socket
unix  13     [ ]         DGRAM                    7853     /dev/log
……太多了……


获取网络流量的统计

通过文件netstat获取

# cat netstat
TcpExt: SyncookiesSent SyncookiesRecv SyncookiesFailed EmbryonicRsts PruneCalled RcvPruned OfoPruned OutOfWindowIcmps LockDroppedIcmps ArpFilter TW TWRecycled TWKilled PAWSPassive PAWSActive PAWSEstab DelayedACKs DelayedACKLocked DelayedACKLost ListenOverflows ListenDrops TCPPrequeued TCPDirectCopyFromBacklog TCPDirectCopyFromPrequeue TCPPrequeueDropped TCPHPHits TCPHPHitsToUser TCPPureAcks TCPHPAcks TCPRenoRecovery TCPSackRecovery TCPSACKReneging TCPFACKReorder TCPSACKReorder TCPRenoReorder TCPTSReorder TCPFullUndo TCPPartialUndo TCPDSACKUndo TCPLossUndo TCPLostRetransmit TCPRenoFailures TCPSackFailures TCPLossFailures TCPFastRetrans TCPForwardRetrans TCPSlowStartRetrans TCPTimeouts TCPLossProbes TCPLossProbeRecovery TCPRenoRecoveryFail TCPSackRecoveryFail TCPSchedulerFailed TCPRcvCollapsed TCPDSACKOldSent TCPDSACKOfoSent TCPDSACKRecv TCPDSACKOfoRecv TCPAbortOnData TCPAbortOnClose TCPAbortOnMemory TCPAbortOnTimeout TCPAbortOnLinger TCPAbortFailed TCPMemoryPressures TCPSACKDiscard TCPDSACKIgnoredOld TCPDSACKIgnoredNoUndo TCPSpuriousRTOs TCPMD5NotFound TCPMD5Unexpected TCPSackShifted TCPSackMerged TCPSackShiftFallback TCPBacklogDrop TCPMinTTLDrop TCPDeferAcceptDrop IPReversePathFilter TCPTimeWaitOverflow TCPReqQFullDoCookies TCPReqQFullDrop TCPRetransFail TCPRcvCoalesce TCPOFOQueue TCPOFODrop TCPOFOMerge TCPChallengeACK TCPSYNChallenge TCPFastOpenActive TCPFastOpenActiveFail TCPFastOpenPassive TCPFastOpenPassiveFail TCPFastOpenListenOverflow TCPFastOpenCookieReqd TCPSpuriousRtxHostQueues BusyPollRxPackets TCPAutoCorking TCPFromZeroWindowAdv TCPToZeroWindowAdv TCPWantZeroWindowAdv TCPSynRetrans TCPOrigDataSent TCPHystartTrainDetect TCPHystartTrainCwnd TCPHystartDelayDetect TCPHystartDelayCwnd TCPACKSkippedSynRecv TCPACKSkippedPAWS TCPACKSkippedSeq TCPACKSkippedFinWait2 TCPACKSkippedTimeWait TCPACKSkippedChallenge
TcpExt: 0 0 2 0 1 0 0 0 0 0 125 0 0 0 0 0 4359 13 395 0 0 43351 262178 49496939 0 269777 27523 23961 22088 0 0 0 0 0 0 00 0 0 10 0 0 1 0 0 0 0 28 29 9 0 0 1 65 103 10 5 0 11 4 0 8 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 18102 16220 0 8 7 6 0 0 0 0 0 0 0 0 1572 0 0 16 16 65741 3 48 1 38 0 0 0 0 0 0
IpExt: InNoRoutes InTruncatedPkts InMcastPkts OutMcastPkts InBcastPkts OutBcastPkts InOctets OutOctets InMcastOctets OutMcastOctets InBcastOctets OutBcastOctets InCsumErrors InNoECTPkts InECT1Pkts InECT0Pkts InCEPkts
IpExt: 0 0 0 0 20515 0 844494896 48090350 0 0 3527522 0 0 993982 0 0 0


对应的通过netstat命令的结果如下:

# netstat -s
Ip:
    994018 total packets received
    0 forwarded    
    0 incoming packets discarded    
    475665 incoming packets delivered    
    369180 requests sent out
Icmp:
    15 ICMP messages received    
    0 input ICMP message failed.
    ICMP input histogram:
        destination unreachable: 14
        echo requests: 1
    2 ICMP messages sent    
    0 ICMP messages failed
    ICMP output histogram:
        destination unreachable: 1
        echo replies: 1
IcmpMsg:
        InType3: 14
        InType8: 1
        OutType0: 1
        OutType3: 1
Tcp:
    169 active connections openings    
    75 passive connection openings    
    0 failed connection attempts    
    13 connection resets received    
    3 connections established    
    403009 segments received    
    325873 segments send out    
    106 segments retransmited    
    5 bad segments received.    
    26 resets sent
Udp:
    52122 packets received    
    1 packets to unknown port received.    
    0 packet receive errors    
    56490 packets sent    
    0 receive buffer errors    
    0 send buffer errors
UdpLite:
TcpExt:
    2 invalid SYN cookies received    
    1 packets pruned from receive queue because of socket buffer overrun    
    125 TCP sockets finished time wait in fast timer    
    4361 delayed acks sent    
    13 delayed acks further delayed because of locked socket
    Quick ack mode was activated 395 times    
    43351 packets directly queued to recvmsg prequeue.    
    262178 bytes directly in process context from backlog    
    49496939 bytes directly received in process context from prequeue    
    269791 packet headers predicted    
    27523 packets header predicted and directly queued to user    
    23975 acknowledgments not containing data payload received    
    22109 predicted acknowledgments    
    10 congestion windows recovered without slow start after partial ack    
    1 timeouts after SACK recovery    
    28 other TCP timeouts
    TCPLossProbes: 29
    TCPLossProbeRecovery: 9
    1 times receiver scheduled too late for direct processing    
    65 packets collapsed in receive queue due to low socket buffer    
    103 DSACKs sent for old packets    
    10 DSACKs sent for out of order packets    
    5 DSACKs received    
    11 connections reset due to unexpected data    
    4 connections reset due to early user close    
    8 connections aborted due to timeout
    TCPDSACKIgnoredNoUndo: 2
    TCPRcvCoalesce: 18102
    TCPOFOQueue: 16220
    TCPOFOMerge: 8
    TCPChallengeACK: 7
    TCPSYNChallenge: 6
    TCPAutoCorking: 1572
    TCPWantZeroWindowAdv: 16
    TCPSynRetrans: 16
    TCPOrigDataSent: 65784
    TCPHystartTrainDetect: 3
    TCPHystartTrainCwnd: 48
    TCPHystartDelayDetect: 1
    TCPHystartDelayCwnd: 38
IpExt:
    InBcastPkts: 20517
    InOctets: 844504429
    OutOctets: 48100640
    InBcastOctets: 3527980
    InNoECTPkts: 994098


获取路由表

通过文件route文件获取

# cat /proc/net/route
Iface	Destination	Gateway 	Flags	RefCnt	Use	Metric	Mask		MTU	Window	IRTT
eth0	00000000	01206F0A	0003	0	0	100	00000000	0	0	0
eth0	00206F0A	00000000	0001	0	0	100	00FFFFFF	0	0	0


通过命令netstat获取结果如下

# netstat -nr
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
0.0.0.0         10.111.32.1     0.0.0.0         UG        0 0          0 eth0
10.111.32.0     0.0.0.0         255.255.255.0   U         0 0          0 eth0


进程的IO信息

通过IO文件获取

# cat /proc/14915/io
rchar: 8909689
wchar: 34256883
syscr: 4344
syscw: 4242
read_bytes: 7847936
write_bytes: 47292416
cancelled_write_bytes: 16384


解释:

  1. rchar:该进程从存储读取的字节数(不准确)

  2. wchar:该进程写入存储的字节数(不准确)

  3. syscr:统计线程中系统调用read()函数的次数,不准确

  4. syscw:统计线程中系统调用write()函数的次数,不准确

  5. read_bytes:直接统计线程实际读磁盘的字节数

  6. write_bytes:直接统计线程实际写磁盘的字节数,这两个值是准确的

  7. cancelled_write_bytes:这个字段主要统计那些线程已经写了但没有写成功的字节数,主要原因在于页截断。举个例子:当一个进程写1MB数据到文件内然后把这个文件删除了,那么这1MB其实是被写取消的,但是该文件中仍旧会记录1MB的写操作

进程的文件描述符相关

/proc/[pid]/fd/文件

/proc/[pid]/fd/是一个目录,该目录中的每一条信息都表示该进程打开的每一个文件。命名方式是文件描述符,并且会以软连接的方式指向真实的文件位置。其中 0 表示标准输入, 1表示标准输出, 2表示标准错误输出,等等。

如果是管道和socket的文件,那么该文件描述符的软连接会指向文件的类型和文件的inode节点。比如type:[inode]这样的格式。

比如socket:[2248868]文件是一个socket,并且它的inode是2248868。对于socket,可以在/proc/net/中通过inode找到更多的信息。

有的文件描述符是没有符合的inode(比如通过epoll_create、eventfd、inotify_init创建的文件描述符), 他们的软连接指向的内容可能就是anon_inode:<file-type>

比如一个epoll文件描述符指向的软连接的内容字符为anon_inode:[eventpoll]

比如有一个命令行程序,需要参数指定输入和输出的文件,但是没有指定这些参数,也没有指定标准输入和输出,那么可以这样使用:

$ foobar -i /proc/self/fd/0 -o /proc/self/fd/1 ...


事实上,在Unix和类Unix的系统中,/proc/self/fd/N 大致上是和 /dev/fd/N想同的。

[root@localhost 14915]# ll /dev/fd//
total 0
lrwx------ 1 root root 64 May 16 09:25 0 -> /dev/pts/1
lrwx------ 1 root root 64 May 16 09:25 1 -> /dev/pts/1
lrwx------ 1 root root 64 May 16 09:25 2 -> /dev/pts/1
lr-x------ 1 root root 64 May 16 09:25 3 -> /proc/31662/fd
[root@localhost 14915]# ll /proc/self/fd
total 0
lrwx------ 1 root root 64 May 16 09:25 0 -> /dev/pts/1
lrwx------ 1 root root 64 May 16 09:25 1 -> /dev/pts/1
lrwx------ 1 root root 64 May 16 09:25 2 -> /dev/pts/1
lr-x------ 1 root root 64 May 16 09:25 3 -> /proc/31670/fd


大多数系统中/proc/self/fd中的0 , 1 , 2 都有提供符号链接/dev/stdin/dev/stdout/dev/stderr

# ll /dev/std{in,out,err}
lrwxrwxrwx 1 root root 15 Mar 30 10:27 /dev/stderr -> /proc/self/fd/2
lrwxrwxrwx 1 root root 15 Mar 30 10:27 /dev/stdin -> /proc/self/fd/0
lrwxrwxrwx 1 root root 15 Mar 30 10:27 /dev/stdout -> /proc/self/fd/1


下面是一个完整的fd的例子

# ll /proc/14915/fd/
total 0
lr-x------ 1 root root 64 May 16 08:44 0 -> /dev/null
l-wx------ 1 root root 64 May 16 08:44 1 -> /var/lib/mysql/log/error.log
l-wx------ 1 root root 64 May 16 08:44 2 -> /var/lib/mysql/log/error.log
lrwx------ 1 root root 64 May 16 08:44 3 -> /var/lib/mysql/binlog/mysql-bin.index
lrwx------ 1 root root 64 May 16 08:44 10 -> /var/lib/mysql/redolog/ib_logfile1
lrwx------ 1 root root 64 May 16 08:44 25 -> socket:[39621]
lrwx------ 1 root root 64 May 16 08:44 26 -> socket:[39623]
lrwx------ 1 root root 64 May 16 08:44 6 -> /tmp/ibQYCDZE (deleted)
……省略……


/proc/[pid]/fdinfo/文件

/proc/[pid]/fdinfo/这是一个目录,目录中的每一条表示该进程打开的每一个文件,并且以文件描述符的方式命名。这个目录中的文件对于进程的拥有者来说是只读的。可以读取文件的内容,以获取相关的文件描述符的信息。文件的内容取决于相应的文件描述符引用的文件的类型。

对于常规的文件和目录,看起来大概如下:

$ cat /proc/12015/fdinfo/4
pos:    1000
flags:  01002002
mnt_id: 21


  • pos 这是一个十进制数字,显示文件的offset

  • flags 这是一个八进制数字,显示文件的访问模式和文件状态

  • mnt_id 从3.15开始,这个ID表示文件的挂载点。具体查看/proc/[pid]/mountinfo

如果是eventfd的文件描述符,可能会看到如下字段(从3.8开始):

pos: 0
flags:    02
mnt_id:   10
eventfd-count:               40
  • eventfd-count 是一个十六进制的数字,表示当前的eventfd的计数


如果是epoll的文件描述符,可能会看到如下字段(从3.8开始):

pos: 0
flags:    02
mnt_id:   10
tfd:        9 events:       19 data: 74253d2500000009
tfd:        7 events:       19 data: 74253d2500000007


如果是inotify的文件描述符,我们会看到如下内容

pos: 0
flags:    00
mnt_id:   11
inotify wd:2 ino:7ef82a sdev:800001 mask:800afff ignored_mask:0 fhandle-bytes:8 fhandle-type:1 f_handle:2af87e00220ffd73
inotify wd:1 ino:192627 sdev:800001 mask:800afff ignored_mask:0 fhandle-bytes:8 fhandle-type:1 f_handle:27261900802dfd73

inotify开头的每一行表示被监控的文件或者目录,每一字段的解释如下:

  • wd 十进制数字,一个监视的文件描述符号

  • ino 十六进制数字,目标文件的inode号

  • sdev 十六进制数字,目标文件所在的设备的ID

  • mask 十六进制数字,被监控的目标文件的mask

  • fhandle-bytesfhandle-typef_handle 十六进制数字

进程相关的挂载信息

/proc/[pid]/mountinfo文件

这个文件包含进程的挂载命名空间中挂载点的信息。

文件内如如下:

# cat mountinfo
18 62 0:17 / /sys rw,nosuid,nodev,noexec,relatime shared:6 - sysfs sysfs rw
19 62 0:3 / /proc rw,nosuid,nodev,noexec,relatime shared:5 - proc proc rw
20 62 0:5 / /dev rw,nosuid shared:2 - devtmpfs devtmpfs rw,size=5022200k,nr_inodes=1255550,mode=755
71 62 202:1 / /boot rw,relatime shared:27 - xfs /dev/xvda1 rw,attr2,inode64,noquota
62 1 253:0 / / rw,relatime shared:1 - xfs /dev/mapper/cl-root rw,attr2,inode64,noquota
73 62 253:2 / /home rw,relatime shared:28 - xfs /dev/mapper/cl-home rw,attr2,inode64,noquota
……省略……


  1. mount ID: mount的唯一ID

  2. parent ID: 父级mount的ID(如果是顶级mount则是自己)

  3. major:minor: 在这个文件系统上的文件的set_dev的值,可参考stat

  4. root: 这个目录在文件系统中的路径

  5. mount point: the pathname of the mount point relative to the process's root directory.

  6. mount options: per-mount options

  7. optional fields: zero or more fields of the form "tag[:value]"; see below

  8. separator: 可选字段

  9. filesystem type: the filesystem type in the form "type[.subtype]"

  10. mount source: filesystem-specific information or "none".

  11. super options: per-superblock options.

/proc/[pid]/mounts文件

该文件得输出内容和系统得mount命令一样。

/proc/[pid]/mountstats文件

文件内容大概如下:

# cat mountstats
device rootfs mounted on / with fstype rootfs
device sysfs mounted on /sys with fstype sysfs
device proc mounted on /proc with fstype proc
device devtmpfs mounted on /dev with fstype devtmpfs
device /dev/mapper/cl-root mounted on / with fstype xfs
device /dev/xvda1 mounted on /boot with fstype xfs
device /dev/mapper/cl-home mounted on /home with fstype xfs
……省略……


比如:

device /dev/sda7 mounted on /home with fstype ext3 [statistics]
(       1      )            ( 2 )             (3 ) (4)

  • 挂载得设备名,如果没有符合得名字则为nodevice

  • 文件系统中得挂载点

  • 文件系统类型

  • 可选的统计和配置信息。 目前该字段只会显示NFS系统导出的信息。

进程OOM相关

/proc/[pid]/oom_adj文件

该文件被用作调整(adjust)分数,而分数最后将会被用于哪个进程在内存溢出的时候被杀掉。

该文件默认值为 0 。

内核会利用该文件的值进行位操作运算来计算该进程的oom_score的分数。

改文件有效的取值范围是 -1615, 加上特殊的值-17, 当值为-17的时候该进程永远不会因为OOM而被杀掉。 

如果最后的分数为正数,那么会增加杀掉的可能性,如果为负数,那么会减少被杀掉的可能性。

在2.6.32内核之后不建议使用该文件。

/proc/[pid]/oom_score文件

该文件显示内核用于评判当OOM的时候,该进程的分数。分数越高,那么该进程很有可能会因为OOM而被杀掉。这个分数的基础是该进程的内存使用量,增加或者降低的因素还包括:

  • 该进程是否使用fork创建了很多子进程(会增加)

  • 进程已经运行了很长时间,或者使用了大量的CPU时间(会降低)

  • 该进程是否有很低的nice值(会增加)

  • 进程是否有特权

  • 进程是否直接访问硬件(会降低)

/proc/[pid]/oom_score_adj文件

该文件可以用于调整选择哪个进程在内存溢出的情况被杀。

取值范围是0(不会杀)1000(杀),用来确定哪个进程是被杀的目标。主要是根据当前内存和交换内存的使用来估计。比如,一个任务使用了所有的内存,那么不良得分为1000,如果正在使用其允许的内存的一半,那么得分为500

可接受取值范围是从-1000到1000,这允许用户空间根据偏好来控制OOM。最低得-1000表示禁用OOM。

因此在用户空间控制每个任务的内存使用是非常方便的。

为了向后兼容,早期的内核版本,/proc/[pid]/oom_adj仍然可以用来调整不良得分。不过其值相对于oom_score_adj是线性缩小的。

小提示:相关的两个内核参数调整

vm.panic_on_oom = 0       #内存不够时内核是否直接panic;默认为0开启    为1时表示关闭此功能      
vm.oom_kill_allocating_task = 1       #oom-killer是否选择当前正在申请内存的进程进行kill





如无特殊说明,文章均为本站原创,转载请注明出处