尊敬的读者您好:笔者很高兴自己的文章能被阅读,但原创与编辑均不易,所以转载请必须注明本文出处并附上本文地址超链接以及博主博客地址:https://blog.csdn.net/vensmallzeng。若觉得本文对您有益处还请帮忙点个赞鼓励一下,笔者在此感谢每一位读者,如需联系笔者,请记下邮箱:zengzenghe@gmail.com,谢谢合作!
一、Python的内存管理机制?
(1)变量与对象
关系图如下:
注:通过is进行引用所指判断,is是用来判断两个引用所指的对象是否相同。
(2)引用计数
在Python中,引用计数是指每个对象都有指向该对象的引用总数
(3)垃圾回收
当Python的某个对象的引用计数降为0时,说明没有任何引用指向该对象,该对象就成为要被回收的垃圾。比如某个新建对象,被分配给某个引用,对象的引用计数变为1。如果引用被删除,对象的引用计数为0,那么该对象就可以被垃圾回收。
(4)内存池机制
Python中有分为大内存和小内存:(256K为界限分大小内存)
1、大内存使用malloc进行分配
2、小内存使用内存池进行分配
3、Python的内存池(金字塔)
① 第3层:最上层,用户对Python对象的直接操作
② 第1层和第2层:内存池,有Python的接口函数PyMem_Malloc实现-----若请求分配的内存在1~256字节之间就使用内存池管理系统进行分配,调用malloc函数分配内存,但是每次只会分配一块大小为256K的大块内存,不会调用free函数释放内存,将该内存块留在内存池中以便下次使用。
③ 第0层:大内存-----若请求分配的内存大于256K,malloc函数分配内存,free函数释放内存。
④ 第-1,-2层:操作系统进行操作
参考文献:【1】https://www.cnblogs.com/geaozhang/p/7111961.html
【2】https://www.jianshu.com/p/fb1d4dc8e367
二、Python的多线程与多进程区别?
(1)下面简单的比较一下线程与进程
① 进程是资源分配的基本单位,线程是CPU执行和调度的基本单位;
② 通信/同步方式:
进程:
通信方式:管道,FIFO,消息队列,信号,共享内存,socket,stream流;
同步方式:PV信号量,管程
线程:
同步方式:互斥锁,递归锁,条件变量,信号量
通信方式:位于同一进程的线程共享进程资源,因此线程间没有类似于进程间用于数据传递的通信方式,线程间的通信主要是用于线程同步。
③ CPU上真正执行的是线程,线程比进程轻量,其切换和调度代价比进程要小;
④ 线程间对于共享的进程数据需要考虑线程安全问题,由于进程之间是隔离的,拥有独立的内存空间资源,相对比较安全,只能通过上面列出的IPC(Inter-Process Communication)进行数据传输;
⑤ 系统有一个个进程组成,每个进程包含代码段、数据段、堆空间和栈空间,以及操作系统共享部分 ,有等待,就绪和运行三种状态;
⑥ 一个进程可以包含多个线程,线程之间共享进程的资源(文件描述符、全局变量、堆空间等),寄存器变量和栈空间等是线程私有的;
⑦ 操作系统中一个进程挂掉不会影响其他进程,如果一个进程中的某个线程挂掉而且OS对线程的支持是多对一模型,那么会导致当前进程挂掉;
⑧ 如果CPU和系统支持多线程与多进程,多个进程并行执行的同时,每个进程中的线程也可以并行执行,这样才能最大限度的榨取硬件的性能;
(2)线程和进程的上下文切换
进程切换过程切换牵涉到非常多的东西,寄存器内容保存到任务状态段TSS,切换页表,堆栈等。简单来说可以分为下面两步:① 页全局目录切换,使CPU到新进程的线性地址空间寻址;② 切换内核态堆栈和硬件上下文,硬件上下文包含CPU寄存器的内容,存放在TSS中;
线程运行于进程地址空间,切换过程不涉及到空间的变换,只牵涉到第二步;
(3)使用多线程还是多进程?
由于python多线程并不是并行执行,因此较适合与I/O密集型程序,多进程并行执行适用于CPU密集型程序;
注:① CPU密集型:程序需要占用CPU进行大量的运算和数据处理;② I/O密集型:程序中需要频繁的进行I/O操作;例如网络中socket数据传输和读取等;
参考文献:【1】https://www.cnblogs.com/yssjun/p/11302500.html
日积月累,与君共进,增增小结,未完待续。