进程
process:运行中的程序一个副本,被载入内存的一个指令集合,是资源分配的单位
进程创建:init第一个进程,centos7系列以上更名为systemd;进程都由父进程创建,fork()
线程:线程是操作系统调度的最小单位,每个进程又可以有多个线程,线程是轮询执行的,因为轮询的速度很快,所以可以看成是并行。
协程是微线程,一个线程可以分为多个协程,同样也是轮询执行,这样的好处是减少CPU的资源消耗,一些比较多而且小的事件可以用携程去处理,减少资源的开销
查看进程中的线程
cat /proc/PID/status |grep -i threads
MMU和TLB
MMU:memory management unit负载虚拟地址转换为物理地址
TLB:translation lookaside buffer用于保存虚拟地址与物理地址映射关系的缓存
程序访问内存地址指向的内存是,cpu不是直接把地址放到内存总线上,而是送到MMU,然后把这个内存地址映射到物理内存地址上,然后通过总线访问内存,程序操作的地址为虚拟地址。
用户和内核空间
每个进程都包含5种不同数据段:代码段、数据段(全局变量等)、BSS段(未初始化全局变量)、堆(heap,存放数组和对象)、栈(临时的局部变量等,后进后出原则)
使用过程中出现的内存问题
内存泄漏(memory leak):指程序申请了一块内存,但是没有使用并且释放,导致这块内存被占用
内存溢出(memory overflow):指申请了一定量空间,但是写入超过了这个空间的数据
内存不足(Out of memory):内存用完后门系统会选一个进程将它杀死
说明
Linux默认是允许memory overcommit的,只要你来申请内存我就给你,寄希望于进程实际上用不到那么多内存,但万一用到那么多了呢?Linux设计了一个OOM killer机制挑选一个进程出来杀死,以腾出
部分内存,如果还不够就继续。也可通过设置内核参数 vm.panic_on_oom 使得发生OOM时自动重启系统。这都是有风险的机制,重启有可能造成业务中断,杀死进程也有可能导致业务中断。所以Linux2.6之后允许通过内核参数 vm.overcommit_memory 禁止memory overcommit
vm.panic_on_oom 决定系统出现oom的时候,要做的操作。接受的三种取值如下
0 - 默认值,当出现oom的时候,触发oom killer
1 - 程序在有cpuset、memory policy、memcg的约束情况下的OOM,可以考虑不panic,而是启动OOM
killer。其它情况触发 kernel panic,即系统直接重启
2 - 当出现oom,直接触发kernel panic,即系统直接重启
vm.overcommit_memory 接受三种取值
0 – Heuristic overcommit handling. 这是缺省值,它允许overcommit,但过于明目张胆的overcommit会被拒绝,比如malloc一次性申请的内存大小就超过了系统总内存。Heuristic的意思是“试探式的”,内核利用某种算法猜测你的内存申请是否合理,它认为不合理就会拒绝overcommit。
1 – Always overcommit. 允许overcommit,对内存申请来者不拒。内核执行无内存过量使用处理。使用这个设置会增大内存超载的可能性,但也可以增强大量使用内存任务的性能。
2 – Don’t overcommit. 禁止overcommit。 内存拒绝等于或者大于总可用 swap 大小以及overcommit_ratio 指定的物理 RAM 比例的内存请求。如果您希望减小内存过度使用的风险,这个设置就是最好的。
Heuristic overcommit算法:
free memory + free swap + pagecache的大小 + SLAB
单次申请的内存大小不能超过以上值,否则本次申请就会失败
kernel设有一个阈值,申请的内存总数超过这个阈值就算overcommit,在/proc/meminfo中可以看到这个阈值的大
CommitLimit 就是overcommit的阈值,申请的内存总数超过CommitLimit的话就算是overcommit。此值通过内核参数vm.overcommit_ratio或vm.overcommit_kbytes间接设置的,vm.overcommit_ratio 是内核参数,缺省值是50,表示物理内存的50%。如果你不想使用比率;直接指定内存的字节数大小,通过另一个内核参数 vm.overcommit_kbytes 即可;
公式如下:
CommitLimit = (Physical RAM * vm.overcommit_ratio / 100) + Swap
进程状态
创建态:进程创建时要申请一块空白PCB(process contorl block),向其中填满控制和管理进程的信息,完成资源分配
就绪态:进程已准备好,已分配到资源,只需要分配到CPU就能立即执行
执行态:就绪状态被调度执行后
阻塞态:在执行的进程由于某些事件(IO请求、申请缓存失败)而暂时无法执行,进程受到阻塞,在满足请求时进入就绪状态等待调用
终止态:进程结束,或出现错误或被系统终止,无法再执行
状态之间转换六种情况
运行——>就绪:
1,主要是进程占用CPU的时间过长,而系统分配给该进程占用CPU的时间是有限的;
2,在采用抢先式优先级调度算法的系统中,当有更高优先级的进程要运行时,该进程就被迫让出CPU,
该进程便由执行状态转变为就绪状态
就绪——>运行:运行的进程的时间片用完,调度就转到就绪队列中选择合适的进程分配CPU
运行——>阻塞:正在执行的进程因发生某等待事件而无法执行,则进程由执行状态变为阻塞状态,如发生了I/O请求
阻塞——>就绪:进程所等待的事件已经发生,就进入就绪队列
以下两种状态是不可能发生的:
阻塞——>运行:即使给阻塞进程分配CPU,也无法执行,操作系统在进行调度时不会从阻塞队列进行挑选,而是从就绪队列中选取
就绪——>阻塞:就绪态根本就没有执行,谈不上进入阻塞态
进程更多的状态:
运行态:running
就绪态:ready
睡眠态:可中断、不可中断
停止态:stopped,暂停于内存中,不会被调度
僵死态:zombie,结束进程,父进程结束前,子进程不关闭,杀死父进程可以关闭僵死态进程
R:running
S: interruptable sleeping
D: uninterruptable sleeping
T: stopped
Z: zombie
+: 前台进程
l: 多线程进程
L:内存分页并带锁
N:低优先级进程
<: 高优先级进程
s: session leader,会话(子进程)发起者
I:Idle kernel thread,CentOS 8 新特性
LRU算法
LRU算法:least recently used近期最少使用算法,释放内存
IPC进程间通信
同主机
pipe 管道
socket 套接字文件
memory-maped file 文件映射
shm shared memory 共享内存
signal 信号
lock
semaphore 信号量
不同主机
rpc remote procedure call
mq 消息队列,生产者和消费者,如kafka、rabbitmq、
进程优先级
进程优先级:
系统优先级:数字越小,优先级越高
0-139(CentOS 4,5),各有140个运行队列和过期队列
0-98,99(CentOS 6)
实时优先级: 99-0 值最大优先级最高
nice值:-20到19,对应系统优先级100-139或9