进程和操作系统的诊断工具
ps
1 |
|
pstree
1 |
|
df
1 |
|
du
1 |
|
TOP 输出
1 |
|
系统态 cpu 时间片占比高,可能意味着系统中存在 race condition,或者有进程在频繁等待底层设备。
用 top 看 cpu,st 意味着物理机上其他虚拟机占用CPU的时间百分比。
符号 | 含义 |
---|---|
18:52:04 | 当前时间 up 10days, 3:49 系统运行时间,格式为:天,时:分 |
1 | user 当前登录用户数 |
load average: 0.00, 0.01, 0.05 | 系统负载,即任务队列的平均长度。三个数值分别为 1分钟、5分钟、15分钟前到现在的平均值 |
当CPU完全空闲的时候,平均负荷为0;当CPU工作量饱和的时候,平均负荷为1。
如果CPU每分钟最多处理100个进程,那么系统负荷0.2,意味着CPU在这1分钟里只处理20个进程;系统负荷1.0,意味着CPU在这1分钟里正好处理100个进程;系统负荷1.7,意味着除了CPU正在处理的100个进程以外,还有70个进程正排队等着CPU处理(load 可以超过 1.0!)。load 其实是 cpu utilization 的一种具象化表示。load 1.0 大致上等于那段时间里 cpu 的 idle time = 0。注意,如果有 4 核 cpu,实际上 cpu 的满负荷是 4.0。
如果只有1分钟的系统负荷大于1.0,其他两个时间段都小于1.0,这表明只是暂时现象,问题不大。
如果15分钟内,平均系统负荷大于1.0(调整CPU核心数之后),表明问题持续存在,不是暂时现象。所以,你应该主要观察”15分钟系统负荷”,将它作为电脑正常运行的指标。
第二、三行为进程和CPU的信息。当有多个CPU时,这些内容可能会超过两行。内容如下:
符号 | 含义 |
---|---|
total | 进程总数 |
running | 正在运行的进程数 |
sleeping | 睡眠的进程数 |
stopped | 停止的进程数 |
zombie | 僵尸进程数 |
%Cpu(s) | |
0.0 us | 用户空间占用CPU百分比 |
0.1 sy | 内核空间占用CPU百分比 |
0.0 ni | 用户进程空间内改变过优先级的进程占用CPU百分比 |
98.7 id | 空闲CPU百分比; |
0.0 wa | 等待输入输出的CPU时间百分比 |
0.0 hi | 硬件CPU中断占用百分比 |
0.0 si | 软中断占用百分比 |
0.0 st | 虚拟机占用百分比 |
最后两行为内存信息。内容如下:
符号 | 含义 |
---|---|
KiB Mem | |
7993560 total | 物理内存总量 |
207064 free | 空闲内存总量 |
723688 used | 使用的物理内存总量 |
7062808 buffer/cache | 用作内核缓存的内存量,TODO待详解:https://blog.csdn.net/Cooling88/article/details/50969013 |
KiB Swap | |
8257532 total | 交换区总量 |
8257356 free | 空闲交换区总量 |
176 used | 使用的交换区总量 |
6479580 avail Mem | 缓冲的交换区总量,内存中的内容被换出到交换区,而后又被换入到内存,但使用过的交换区尚未被覆盖,该数值即为这些内容已存在于内存中的交换区的大小,相应的内存再次被换出时可不必再对交换区写入 |
进程信息区统计信息区域的下方显示了各个进程的详细信息。首先来认识一下各列的含义。
序号 | 列名 | 含义 |
---|---|---|
a | PID | 进程id |
b | PPID | 父进程id |
c | RUSER | Real user name |
d | UID | 进程所有者的用户id |
e | USER | 进程所有者的用户名 |
f | GROUP | 进程所有者的组名 |
g | TTY | 启动进程的终端名。不是从终端启动的进程则显示为 ? |
h | PR | 优先级 |
i | NI | nice值。负值表示高优先级,正值表示低优先级 |
j | P | 最后使用的CPU,仅在多CPU环境下有意义 |
k | %CPU | 上次更新到现在的CPU时间占用百分比。这个数值是针对单核的 cpu 时间统计,如果 cpu 是多核,这个数值有可能超过 100% |
l | TIME | 进程使用的CPU时间总计,单位秒 |
m | TIME+ | 进程使用的CPU时间总计,单位1/100秒,比 TIME 多小数点后2位。257:14.655 代表257分钟14.655秒 |
n | %MEM | 进程使用的物理内存百分比 |
o | VIRT | 进程使用的虚拟内存总量,单位kb。VIRT=SWAP+RES |
p | SWAP | 进程使用的虚拟内存中,被换出的大小,单位kb。 |
q | RES | 进程使用的、未被换出的物理内存大小,单位kb。RES=CODE+DATA |
r | CODE | 可执行代码占用的物理内存大小,单位kb |
s | DATA | 可执行代码以外的部分(进程数据段+栈+堆)占用的物理内存大小,单位kb |
t | SHR | 共享内存大小,单位kb。 The amount ofshared memory used by a task. It simply reflects memory that could bepotentially shared with other processes. (一个任务使用共享内存的总数。它只是反映可能与其它进程共享的内存)也就是这个进程使用共享内存的大小。 |
u | nFLT | 页面错误次数 |
v | nDRT | 最后一次写入到现在,被修改过的页面数。 |
w | S | 进程状态(D=不可中断的睡眠状态,R=运行,S=睡眠,T=跟踪/停止,Z=僵尸进程) |
x | COMMAND | 命令名/命令行 |
y | WCHAN | 若该进程在睡眠,则显示睡眠中的系统函数名 |
z | Flags | 任务标志,参考 sched.h |
VIRT 虚拟内存中含有共享库、共享内存、栈、堆,所有已申请的总内存空间。VIRT 实际上是整个地址空间里被使用的大小,包括物理内存,和被映射进虚拟内存的文件空间。VIRT包含了在已经映射到物理内存空间的部分和尚未映射到物理内存空间的部分总和。比如进程 A 的地址空间大概有 10g,已经切出了 4 个内存块一共 2g正在用,也被映射到了物理内存上,还有8g 的内存块还未映射上去,这部分也算在 VIRT 里。有一些人认为 VIRT = RES + SWAP。
RES 是进程正在使用的内存空间(栈、堆),申请内存后该内存段已被重新赋值。 RSS 是进程占用内存页的数量,RES 是进程使用的内存大小,不包括cache。它们都指进程常驻物理内存的大小,但单位不同。
SHR 是共享内存正在使用的空间。实际上指的是多个进程的多个逻辑内存页映射到物理内存的同一个物理内存页里,参考这里。
SWAP 交换的是已经申请,但没有使用的空间,包括(栈、堆、共享内存)。
DATA 是进程栈、堆申请的总空间。
实际上单纯的 top 是不一定看得见进程里的 swap 消耗的。用以下命令可以看。
1 |
|
查看 top 消耗内存的进程
1 |
|
或者
From inside top you can try the following:
Press SHIFT+f
Press the Letter corresponding to %MEM
Press ENTER
如果 load 高但 cpu 使用率低,则意味着等待磁盘I/O完成的进程过多,导致进程队列长度过大,但是cpu运行的进程却很少,这样就导致负载过大,但cpu使用率低。
free(非常重要)
total | used | free | shared | buffers | cached | |
---|---|---|---|---|---|---|
Mem: | 16318880 | 16202128 | 116752 | 0131300 | 11917768 | |
-/+ buffers/cache: | 4153060 | 12165820 | ||||
Swap: | 8386552 | 0 | 8386552 |
所有的数据默认都是 KB,第一行有六个值:
- total:物理内存大小,就是机器实际的内存
- used:已使用的内存大小,这个值包括了 cached 和 应用程序实际使用的内存
- free:未被使用的内存大小
- shared:共享内存大小,是进程间通信的一种方式
- buffers:被缓冲区占用的内存大小,后面会详细介绍
- cached:被缓存占用的内存大小,后面会详细介绍
其中有
total = used + free
下面一行,代表应用程序实际使用的内存:
- 前一个值表示 - buffers/cached,即 used - buffers/cached,表示应用程序实际使用的内存
- 后一个值表示 + buffers/cached,即 free + buffers/cached,表示理论上都可以被使用的内存-CentOS 里很多内存会被 cached 提前用掉。
不难看出来,这两个值加起来也是 total。
第三行表示 swap 的使用情况:总量、使用的和未使用的。
选项可以参考:《10 ‘free’ Commands to Check Memory Usage in Linux》
uptime
这个命令的输出基本被 top 覆盖了。
uptime
20:33:31 up 390 days, 3:44, 1 user, load average: 0.25, 0.25, 0.18
netstat
1 |
|
lsof
查看端口利器:
1 |
|
iotop
pmap
1 |
|
smap
vmstat
1 |
|
strace
https://tech.meituan.com/2019/01/03/spring-boot-native-memory-leak.html
/proc 目录
当代 OS X 里没有这个目录。
/proc 目录是一个 unix 常见的伪文件系统(in-memory pseudo-file system)或者虚拟文件系统(virtual file system)-意味着这里面的内容不存在于磁盘上,而存在于内存里,是 runtime 运行态数据。实际上,它是 procfs 在启动时(at boot time)被 mount 到 /proc 目录的结果。 procfs 是进程文件系统 (file system) 的缩写,包含一个伪文件系统(启动时动态生成的文件系统),用于通过内核访问进程信息。由于 /proc 不是一个真正的文件系统,它也就不占用存储空间,只是占用有限的内存。
通过查询这个文件夹下的内容,用户可以获得:
- 硬件信息
- 进程运行态信息
实际上 proc目录下的文件,保存的是整个系统的信息。
用户甚至可以通过修改这个文件夹下的内容来改变操作系统的行为。
这个文件夹下很多文件的内容的大小为 0,但都可以 cat-可以理解为从设备里实时读取数据而无法显示文件大小。
如:
1 |
|
常见的条目信息
所有文件的信息可以用这个命令查看:
1 |
|
具体内容:
- /proc/cmdline – Kernel command line information. 内核命令行参数信息-不同于进程命令行参数信息
- /proc/console – Information about current consoles including tty. 当前控制台(包括 tty)信息,不是所有 os 都有。
- /proc/devices – Device drivers currently configured for the running kernel. 为内核配置的设备驱动。系统已经加载的所有块设备和字符设备的信息;
- /proc/dma – Info about current DMA channels. DMA 通道信息。
- /proc/fb – Framebuffer devices. 帧缓冲设备。
- /proc/filesystems – Current filesystems supported by the kernel. 当前内核支持的文件系统 + 节点(nodev)信息
- /proc/iomem – Current system memory map for devices. 当前针对设备的内存映射。
- /proc/ioports – Registered port regions for input output communication with device. 输入输出设备的注册端口区。
- /proc/loadavg – System load average. 系统负载平均值。其前三列分别表示最近1分钟、5分钟及15分的平均负载。反映了当前系统的繁忙情况。
- /proc/locks – Files currently locked by kernel.内核当前锁住的文件。
- /proc/meminfo – Info about system memory (see above example). 系统的内存信息。常由free命令使用。
- /proc/misc – Miscellaneous drivers registered for miscellaneous major device. 为主要 Miscellaneous 杂项设备注册的 Miscellaneous 杂项驱动
- /proc/modules – Currently loaded kernel modules. 当前已加载的内核模块。
- /proc/mounts – List of all mounts in use by system. 当前系统的所有挂载文件系统。如 /dev/vda1 / ext4 rw,relatime,barrier=1,data=ordered 0 0
- /proc/partitions – Detailed info about partitions available to the system. 系统可用分区。如 vda、vdb。块设备每个分区的主设备号(major)和次设备号(minor)等信息,同时包括每个分区所包含的块(block)数目;
- /proc/pci – Information about every PCI device. pci 设备信息
- /proc/stat – Record or various statistics kept from last reboot. 上次重启以来保存的各种各样的记录。
- /proc/swap – Information about swap space. swap 空间的信息。和 meminfo 里信息不同。如 /dev/vdb1 partition 2096440 805472 -1。
- /proc/uptime – Uptime information (in seconds). 系统 uptime 信息。uptime 命令并不是直接从这里 cat 信息。
- /proc/version – Kernel version, gcc version, and Linux distribution installed. 内核版本。
- /proc/kcore 物理内存的镜像,它会显示文件大小的,但是不占用实际的磁盘空间,所以,看到该文件非常大,也不用担心。kcore文件的大小等于已被使用的物理内存的大小加上4k,该文件可以使用gdb工具调试以查看内核中的数据结构。
- /proc/diskstats 磁盘设备的磁盘I/O统计信息列表;
- /proc/net/dev 网络流入流出的统计信息,包括接收包的数量、发送包的数量,发送数据包时的错误和冲突情况等。
- /proc/version 当前系统运行的内核版本号,在很多发行版中,还会显示系统安装的gcc版本;
- /proc/vmstat 当前系统虚拟内存的统计数据。
- /proc/crypto list of available cryptographic modules 当前内核可用的加密模块,如 crc32c、md5、sha1。
- /proc/kmsg holding messages output by the kernel dmesg是 打印内核启动过程的所有信息的命令,实际上就是读的/proc/kmsg也是打印内核的信息。这里存的是内核日志的信息。
- /proc/scsi information about any devices connected via a SCSI or RAID controller 通过 SCSI 或者 RAID 控制器连接的设备的信息。
其他详细解释还可以看这里:
中文详解,很有价值
Discover The Possibilities Of The /Proc Directory(注意里面对 net 文件夹的解释)
Linux Programmer’s Manual PROC(5)
Chapter 1. Linux Filesystem Hierarchy
进程目录
进程目录下文件的含义:
- /proc/PID/cmdline Command line arguments. 类似于 ps aux 里每个进程的详细输出。
- /proc/PID/cwd Link to the current working directory. 是一个符号链接,指向进程的运行目录;比如启动 tomcat,本质上是在 tomcat 的 webapps 某个目录里启动 /path_to_java/bin/java + jvm 启动参数的执行结果。
- /proc/PID/cpu Current and last cpu in which it was executed. 现在和上一个进程用于被执行的 cpu。
- /proc/PID/environ Values of environment variables. 所有环境变量的值,去掉了空格等 delimiter。
- /proc/PID/exe Link to the executable of this process. 进程的可执行文件,比如 java。
- /proc/PID/fd Directory, which contains all file descriptors. 包含所有打开的文件描述符的文件夹。非常大。
- /proc/PID/maps Memory maps to executables and library files.可执行文件和库的内存映射(表)。
- /proc/PID/mem Memory held by this process. 进程持有的内存。
/proc/PID/root Link to the root directory of this process. 到这个进程的 root 目录的链接 - 对于 Java 就是 Java_HOME 变量。
/proc/PID/stat Process status. 进程状态信息。内部信息很重要,见:https://blog.csdn.net/cybertan/article/details/7596633
/proc/PID/statm Process memory status information. 见:https://blog.csdn.net/dutsoft/article/details/51250374
/proc/PID/status Process status in human readable form. stat 的可读形式,应该优先读这里,具体细节再去读 /proc/PID/stat。
重点介绍/proc/PID/status
的格式:
- VmPeak 进程所使用的虚拟内存的峰值
- VmSize 进程当前使用的虚拟内存的大小
- VmLck 已经锁住的物理内存的大小(锁住的物理内存不能交换到硬盘)
- VmHWM 进程所使用的物理内存的峰值
- VmRSS 进程当前使用的物理内存的大小
- VmData 进程占用的数据段大小
- VmStk 进程占用的栈大小
- VmExe 进程占用的代码段大小(不包括库)
- VmLib 进程所加载的动态库所占用的内存大小(可能与其它进程共享)
- VmPTE 进程占用的页表大小(交换表项数量)
- VmSwap 进程所使用的交换区的大小
jvm 自己的本地栈大小可以通过指标看出来。