1、Python的内存管理机制是什么?
总结的说就是,引用计数、垃圾回收、内存池机制
垃圾回收:当程序中使用的对象越来越多,占据的内存越来越大,垃圾回收就会起作用,回收不再使用的对象;垃圾回收是以引用计数为主,标记消除和分代回收为辅的回收机制,标记消除和分代回收只要是为了解决循环引用的问题。
引用计数:当一个变量保存了一个对象的引用时,该对象的引用计数+1;当使用del来删除该对象时,该对象并不会直接被回收,而是它的引用计数-1,当多次del后,如果该对象的引用计数变为了0,该对象才会在内存中被彻底删除。
标记消除:当两个对象的引用计数同时为1,且只存在它们两个之间的循环引用,那么这两个对象要被回收
分代回收:分代回收是为了更合理的调用标记消除而存在的,具体实现如下
- 新创建的对象为0代
- 每进行一次标记消除,该存活对象的代数+1
- 代数越高的对象,进行标记消除的间隔时间(阈值)越长
内存池机制:python的内存池机制主要分为大小内存进行管理,如下
- 第3层,用户直接对对象进行操作
- 第1、2层,请求内存空间<256K,由操作系统来直接分配,调用python的函数接口Pymen_Malloc,由内存池来进行分配一块空间大小为256K的区域,用完之后该块内存区域直接放入内存池以便下次使用
- 第0层,请求内存空间>256K,由底层模块C的malloc()来分配内存,free()来释放内存
2、Python 的内存管理的优化方法?
- 手动进行垃圾回收
- 调高垃圾回收阈值
- 避免循环引用(手动解循环引用和使用弱循环)
3、Python中内存泄漏 ?
指由于疏忽或错误导致应用程序未能释放不再使用的内存空间的情况。
内存泄漏并非指物理上的内存空间的消失。而是应用程序使用了某块内存之后,由于设计错误,失去了该块内存的使用控制权,导致内存的浪费,造成应用运行速度变慢甚至系统奔溃等严重后果。
4、如何避免内存泄漏?
循环引用是导致内存泄漏的主要元凶,以此可以
- 使用del来删除不再使用的对象实体,可以解决绝大部分内存泄漏问题
- 使用python的扩展模块gc来查看不能回收对象的详细信息
- 使用sys.getrefcount(obj)来查看对象的引用计数次数,根据返回值判断是否存在内存泄漏
5、三大常见的内存泄漏
- 无穷大导致内存泄漏
- 循环引用导致内存泄漏
- 外面库导致内存泄漏
6、python中的内存溢出
是指申请的内存空间大小却没有足够的内存的情况
7、python中的内存溢出的原因
- 内存的数据加载量过大,如数据库一次性读取大量的数据
- 集合类引用了大量的对象实体,忘记清除
- 死循环或循环中创建了大量的实体对象
8、python中的内存溢出解决方案
- 物理上增加内存
- 查看错误日志,看看内存溢出之前有没有其它的异常
- 查看代码,看看
. 有没有存在一次性读取大量数据的数据库查询语句
. 有没有死循环
. 有没有循环中创建大量的对象实体
. 看看list、map等类使用后,有没有清除 - 使用内存管理工具动态查看内存的情况
9、python退出时是否释放所有内存分配?
否,循环引用对象、全局命名空间引用的变量,在python退出的时候是不会被释放的,另外c库保留部分也不会被释放