每一种语言都有自身的一个内存管理机制,那么在python中是如何进行内存管理的?
总所周知,python是一种动态数据类型的语言,在就是说,在python中变量无须事先声明、变量无需指定类型,我们甚至无需关心它的内存管理,那么,python是如何做到如此智能的,内存资源它是如何回收的?
我们可以从这三个方面说起:
一、python的内存管理机制----引用计数
在python内部我们通过引用计数来保持追踪内存中的对象,python内部记录了对象有多个个引用。通俗点说,当你创建一个对象的同时python内部会创建一个引用计数,来进行记录,当这个对象不在需要的时候,即这个对象的引用计数为0的时候,它会被垃圾回收器自动回收。
那么问题来了,什么时候引用计数会增长,什么时候引用计数会减少呢?
引用计数增长的情况:
1.对象被创建的时候:
比如:a = 10
2.进行赋值引用的时候:
比如:b = a
3.作为参数传递给函数的时候:
比如:f(a)
4.作为元素存在于其他对象中的时候:
python的一个容器对象,比如列表、字典等等可以包含多个对象,而实际上容器中包含的并不是元素对象本身,是指向各个元素对象的引用。
比如:list1 = [a,1,2,3]
引用环
两个对象可能相互引用,从而构成所谓的引用环,比如:
list1 = []
list2 = [list1]
list1.append(list2)
一个对象有时候,也有可能构成引用环
list1 = []
list1.append(list1)
引用环会给垃圾回收机制带来很大的麻烦,因为它的引用计数不为0,但是有时候又没有什么作用。这样就会造成内存的浪费,因此垃圾回收机制还有一个循环垃圾回收器,确保释放循环引用对象。
引用计数减少
1.本地的引用离开了它的作用域
例如:f(a)调用结束的时候,a的引用减1
2.对象的别名被显式的销毁
例如:del a 或者del b
3.对象的别名被赋值给其他的对象
例如:b = 20
4.对象从一个集合中移除
例如:list1.remove(a)
5.集合本身被销毁
例如:del list1;
二、垃圾回收机制
当python中的对象越来越多,占据的内存也会越来越大,此时我们需要启动垃圾回收,将没用的对象清除。
原理:
当python的某个对象的引用计数降为0时,说明该对象没有任何引用指向它,那么此时该对象就即将成为被回收的垃圾。因此垃圾回收器回收的都是为引用计数为0的对象。
del的本质
使用del可以减少引用计数,当垃圾回收器启动的时候,扫描到当前引用计数为0的对象的时候,将其所占的内存清空。
注意事项:
1.垃圾回收器回收的时候,python不能进行其他的任务,频繁的垃圾回收会大大降低python的工作效率。
2.python只会在特定的条件下,自动启动垃圾回收。
3.当python运行时,会记录其中分配对象,和取消分配对象的次数,当两者的差值高于某个阀值的时候,垃圾回收器才会启动。
三、内存池机制
python中有分为大内存和小内存(256k为界限分大小内存)
1、大内存使用malloc进行分配
2.小内存使用内存池进行分配
3、python的内存池(金字塔)
第3层:最上层,用户对python对象的的直接操作
第一层与第二层:内存池,有python的接口函数PyMem_Malloc实现【注意一般情况下用于内存小于256k的,当前层可以直接分配】。
第0层:大内存,若请求分配的内存大于256k,c中malloc函数分配内存,free函数释放内存。
第-1,-2层:操作系统进行操作