linux进程内存空间
在free命令中显示的buffer和cache,它们都是占用内存:
buffer : 作为buffer cache的内存,是块设备的读写缓冲区,更靠近存储设备,或者直接就是disk的缓冲区。
cache: 作为page cache的内存, 文件系统的cache,是memory的缓冲区。
如果cache 的值很大,说明cache住的文件数很多。如果频繁访问到的文件都能被cache住,那么磁盘的读IO 必会非常小。
page cache(页面缓存)
Page cache 也叫页缓冲或文件缓冲,是由好几个磁盘块构成,大小通常为4k,在64位系统上为8k,构成的几个磁盘块在物理磁盘上不一定连续,文件的组织单位为一页, 也就是一个page cache大小,文件读取是由外存上不连续的几个磁盘块,到buffer cache,然后组成page cache,然后供给应用程序。
Page cache在linux读写文件时,它用于缓存文件的逻辑内容,从而加快对磁盘上映像和数据的访问。具体说是加速对文件内容的访问,buffer cache缓存文件的具体内容——物理磁盘上的磁盘块,这是加速对磁盘的访问
Buffer cache(块缓存)
Buffer cache 也叫块缓冲,是内存对物理磁盘上的一个磁盘块进行的缓冲,其大小为通常为1k,磁盘块也是磁盘的组织单位。设立buffer cache的目的是为在程序多次访问同一磁盘块时,减少访问时间。系统将磁盘块首先读入buffer cache,如果cache空间不够时,会通过一定的策略将一些过时或多次未被访问的buffer cache清空。程序在下一次访问磁盘时首先查看是否在buffer cache找到所需块,命中可减少访问磁盘时间。不命中时需重新读入buffer cache。对buffer cache的写分为两种,一是直接写,这是程序在写buffer cache后也写磁盘,要读时从buffer cache上读,二是后台写,程序在写完buffer cache后并不立即写磁盘,因为有可能程序在很短时间内又需要写文件,如果直接写,就需多次写磁盘了。这样效率很低,而是过一段时间后由后台写,减少了多次访磁盘的时间。
Buffer cache是由物理内存分配,Linux系统为提高内存使用率,会将空闲内存全分给buffer cache ,当其他程序需要更多内存时,系统会减少cache大小。
Swap space(交换空间)
Swap space交换空间,是虚拟内存的表现形式。系统为了应付一些需要大量内存的应用,而将磁盘上的空间做内存使用,当物理内存不够用时,将其中一些暂时不需的数据交换到交换空间,也叫交换文件或页面文件中。做虚拟内存的好处是让进程以为好像可以访问整个系统物理内存。因为在一个进程访问数据时,其他进程的数据会被交换到交换空间中。
Swap cache(交换缓存)
swap cache,它表示交换缓存的大小。Page cache是磁盘数据在内存中的缓存,而swap cache则是交换分区在内存中的临时缓存。
Page cache和Buffer cache的区别
磁盘的操作有逻辑级(文件系统)和物理级(磁盘块),这两种Cache就是分别缓存逻辑和物理级数据的。
假设通过文件系统操作文件,那么文件将被缓存到Page Cache,如果需要刷新文件的时候,Page Cache将交给Buffer Cache去完成,因为Buffer Cache就是缓存磁盘块的。
也就是说,直接去操作文件,那就是Page Cache区缓存,用dd等命令直接操作磁盘块,就是Buffer Cache缓存的东西。
Page cache实际上是针对文件系统的,是文件的缓存,在文件层面上的数据会缓存到page cache。文件的逻辑层需要映射到实际的物理磁盘,这种映射关系由文件系统来完成。当page cache的数据需要刷新时,page cache中的数据交给buffer cache,但是这种处理在2.6版本的内核之后就变的很简单了,没有真正意义上的cache操作。
Buffer cache是针对磁盘块的缓存,也就是在没有文件系统的情况下,直接对磁盘进行操作的数据会缓存到buffer cache中,例如,文件系统的元数据都会缓存到buffer cache中。简单说来,page cache用来缓存文件数据,buffer cache用来缓存磁盘数据。在有文件系统的情况下,对文件操作,那么数据会缓存到page cache,如果直接采用dd等工具对磁盘进行读写,那么数据会缓存到buffer cache。
Buffer(Buffer Cache)以块形式缓冲了块设备的操作,定时或手动的同步到硬盘,它是为了缓冲写操作然后一次性将很多改动写入硬盘,避免频繁写硬盘,提高写入效率。
Cache(Page Cache)以页面形式缓存了文件系统的文件,给需要使用的程序读取,它是为了给读操作提供缓冲,避免频繁读硬盘,提高读取效率。
综合监控工具 glances
实时监控 CPU,内存,磁盘,网络等指标
支持彩色显示和动态刷新
可通过 Web 界面远程访问
低资源占用,适合长期运行
支持插件扩展功能
1 | sudo apt update |
1 | sudo yum install epel-release |
1 | pip install glances |
-b: 以Byte为单位显示网卡数据速率
-d: 关闭磁盘I/O模块
-f /path/to/somefile: 设定输入文件位置
-o {HTML|CSV}:输出格式
-m: 禁用mount模块
-n: 禁用网络模块
-t #: 延迟时间间隔
-1:每个CPU的相关数据单独显示
1 | glances -t 2 # 设置刷新间隔为2秒(默认1秒) |
实例:
1 | #监控特定进程 |
glances 配置文件
glances 的配置文件通常位于 <font style="color:rgb(51, 51, 51);background-color:rgb(250, 252, 253);">~/.config/glances/glances.conf</font>,你可以通过编辑这个文件来永久修改默认设置。
信号发送 kill
内部命令,可用来向进程发送控制信号,以实现对进程管理,如果不指定信号,默认会发送 TERM 信号(15),即终止。 若仍无法终止该程序,可使用 SIGKILL(9) 信息尝试强制删除程序。每个信号对应一个数字,信号名称以 SIG 开头
用于终止正在运行的进程,
kill -l /trap -l:显示当前系统可用信号
1 | kill #结束指定PID的进程 |
常用信号
1) SIGHUP 无须关闭进程而让其重读配置文件
2) SIGINT 中止正在运行的进程;相当于Ctrl+c
3) SIGQUIT 相当于ctrl+\
9) SIGKILL 强制杀死正在运行的进程,可能会导致数据丢失,慎用!
15) SIGTERM 终止正在运行的进程,默认信号
18) SIGCONT 继续运行
19) SIGSTOP 后台休眠
也可以在终端中使用组合键发送信号。例如,Ctrl+C 发送 SIGINT信号,Ctrl+S 发送 SIGSTOP 信号,Ctrl+Q 发送 SIGCONT 信号。
可以使用trap命令处理Bash中的信号。例如,在脚本中添加trap date SIGINT,脚本会打印收到 SIGINT 的日期。
SIGINT
SIGINT 是按下 Ctrl+C 时发出的信号。默认操作是终止进程。
SIGTERM 和 SIGQUIT
SIGTERM 和 SIGQUIT 信号旨在终止进程。在这种情况下,特别要求结束进程。当使用 kill 命令时,SIGTERM 是默认信号。
当发送 SIGTERM 时,进程有时会在退出前执行一个清理例程。还可以处理 SIGTERM,在退出前请求确认。编写一个名为handle_sigterm.sh 的脚本,只有当用户发送两次信号时才终止:
SIGKILL
当进程收到 SIGKILL 信号时,它就会被终止。这是一个特殊的信号,因为它不能被忽略,也不能改变它的行为。
使用该信号强制终止进程。需要小心,因为进程将无法执行任何清理例程。
使用 SIGKILL 的一种常见方法是先发送 SIGTERM。会给进程一些时间来终止,也可能会发送几次 SIGTERM。如果进程没有自行结束,就需要发送SIGKILL 终止它
重写前面的示例,尝试处理 SIGKILL 并请求确认:
SIGINT 与 SIGTERM、SIGQUIT 和 SIGKILL 的关系
SIGINT、SIGTERM、SIGQUIT 和 SIGKILL 的默认操作是终止进程。不过,SIGTERM、SIGQUIT 和 SIGKILL 被定义为终止进程的信号,而SIGINT 则被定义为用户请求的中断。
特别是,如果发送 SIGINT(或按 Ctrl+C),根据进程和情况的不同,它的行为也会不同。因此,不应该完全依赖 SIGINT 来完成进程。由于 SIGINT 是用户发送的信号,进程之间通常使用其他信号进行通信。
例如,父进程通常会向其子进程发送 SIGTERM 以终止它们,即使 SIGINT也有同样的效果。 在 SIGQUIT 的情况下,它会生成核心转储,这对调试非常有用。
在 SIGKILL 之外,应该选择 SIGTERM 来终止进程。SIGTERM 是首选方式,因为进程有机会优雅地终止。
由于进程可以覆盖 SIGINT、SIGTERM 和 SIGQUIT 的默认操作,因此可能出现这三个信号都无法结束进程的情况。此外,如果进程被挂起,它可能不会响应任何这些信号。在这种情况下,只能通过 SIGKILL 来终止进程。
读取最大线数
内核参数 threads-max 控制着线程的最大数量
该参数在 /proc/sys/kernel/threads-max 文件中定义。
sysctl 命令也可以获取线程最大值
kernel.pid_max 和 vm.max_map_count 还指定了另外两个限制,它们也会在峰值负载时阻止新线程的创建。
pid_max 参数指定了 PID 的最大值:
上面的 kernel.pid_max 值 4194304 意味着内核最多可同时执行 4194304 个进程。
max_map_count 参数指定一个进程可拥有的虚拟内存区域(VMA)的最大数量:







