线程与进程的区别
1、一个程序至少有一个进程,一个进程至少有一个线程;
2、线程的划分尺度小于进程,使得多线程程序的并发性高;
3、进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率
进程的结构
在Linux系统中,采用虚拟内存管理技术,每个进程都有自己独立的地址空间。这片地址空间的大小为4G(举例)的线性虚拟内存空间,进程在使用是都是该虚拟内存的虚拟地址,无法直接访问到物理内存地址,这种使用虚拟地址比直接访问物理地址更加安全,且内存空间的利用率也更充分,能够使用更大的地址空间。
4G的进程地址空间被分为两个部分:用户空间和内核空间
,用户空间划分在0-3G,内核空间划分为3-4G。用户进程在通常情况下只能访问用户空间的虚拟地址,不能访问内核地址,只有用户进程使用系统调用时才可以访问到内核空间。后续的进程间通信中的管道通信中两个进程实现通信的原理就是通过访问内核地址实现,但内核地址的访问也有不同
下面具体介绍用户空间,用户空间包括以下几个功能区(通常称为段)
只读段:具有只读属性,包含程序代码和只读数据
数据段:存放着全局变量的静态变量。其中初始化数据段存放现实初始化的全局变量的静态变量,未初始化数据段,此段通常被称为BSS段,存放未初始化的全局变量和静态变量。
栈:由系统制动分配释放,存放函数的参数值、局部变量的值、返回地址等。
堆:存放动态分配的数据,一般由程序员动态分配和释放,若程序员不释放,在程序结束后一般会由操作系统回收。
共享库的内存映射区:这是Linux动态链接器和其他共享库代码的映射区域。
OOM报警
内存不足:OOM
Jul 10 10:20:30 kernel: Out of memory: Kill process 9527 (java) score 88 or sacrififice child
原因:
- 给应用分配内存太少:比如虚拟机本身可使用的内存(一般通过启动时的VM参数指定)太少。
- 应用用的太多,并且用完没释放,浪费了。此时就会造成内存泄露或者内存溢出。
解决方法
1,限制部分进程的内存使用,并且降低程序的worker数量,从而降低内存使用
2,给系统增加swap空间
3,释放缓存(不建议生产中用,试验可用):echo 3 > /proc/sys/vm/drop_caches
进程状态
相关工具使用方法可查看进程及数组相关命令简介
ps aux
STAT:进程状态显示
R:running
S: interruptable sleeping D: uninterruptable sleeping
T: stopped
Z: zombie
+: 前台进程
l: 多线程进程
L:内存分页并带锁
N:低优先级进程
<: 高优先级进程
s: session leader,会话(子进程)发起者
I:Idle kernel thread,CentOS 8 新特性
运行态
:进程在运行队列中,代表我已经准备好了,随时可以调度。只有在运行队列里的进程才叫做运行态,而运行态不代表正在运行,代表已准备就绪
终止态
:进程结束,或出现错误,或被系统终止,进入终止状态。无法再执行
阻塞
:正在执行的进程由于某些事件(I/O请求,申请缓存区失败)而暂时无法运行,进程受到阻塞。在满足请求时进入就绪状态等待系统调用
进程挂起
:一个进程对应的代码和数据被操作系统因为到达分配资源时间而导致操作系统将该进程的代码和数据临时地置换到磁盘当中,此时叫做进程挂起
僵尸态
zombie,僵尸态,结束进程,父进程结束前,子进程不关闭,杀死父进程可以关闭僵尸态的子进程
[root@centos8 ~]#bash
[root@centos8 ~]#echo $BASHPID
1809
[root@centos8 ~]#echo $PPID
1436
#将父进程设为停止态
[root@centos8 ~]#kill -19 1436
#杀死子进程,使其进入僵尸态
[root@centos8 ~]#kill 1809
[root@centos8 ~]#ps aux #可以看到上面图示的结果,STAT为Z,表示为僵尸态
#恢复或杀死父进程
[root@centos8 ~]#kill -18 1436
#或者
[root@centos8 ~]#kill -9 1436
#再次观察,可以僵尸态的进程不存在了
[root@centos8 ~]#ps aux