类型并对变量进行赋值) 。
二、引用计数:
Python采用了类似Windows内核对象一样的方式来对内存进行管理 。每一个对象 , 都维护这一个对指向该对对象的引用的计数 。如图所示(图片来自Python核心编程)
x = 3.14
y = x
我们首先创建了一个对象3.14 , 然后将这个浮点数对象的引用赋值给x , 因为x是第一个引用 , 因此 , 这个浮点数对象的引用计数为1. 语句y =
x创建了一个指向同一个对象的引用别名y , 我们发现 , 并没有为Y创建一个新的对象 , 而是将Y也指向了x指向的浮点数对象 , 使其引用计数为2.
我们可以很容易就证明上述的观点:
变量a 和 变量b的id一致(我们可以将id值想象为C中变量的指针).
我们援引另一个网址的图片来说明问题:对于C语言来讲 , 我们创建一个变量A时就会为为该变量申请一个内存空间 , 并将变量值
放入该空间中,当将该变量赋给另一变量B时会为B申请一个新的内存空间 , 并将变量值放入到B的内存空间中 , 这也是为什么A和B的指针不一致的原因 。如图:
而Python的情况却不一样 , 实际上 , Python的处理方式和Javascript有点类似 , 如图所示 , 变量更像是附在对象上的标签(和引用的
定义类似) 。当变量被绑定在一个对象上的时候 , 该变量的引用计数就是1 , (还有另外一些情况也会导致变量引用计数的增加),系统会自动维护这些标签 , 并定
时扫描 , 当某标签的引用计数变为0的时候 , 该对就会被回收 。
三、内存池机制
Python的内存机制以金字塔行 , -1 , -2层主要有操作系统进行操作 ,
第0层是C中的malloc , free等内存分配和释放函数进行操作;
第1层和第2层是内存池 , 有Python的接口函数PyMem_Malloc函数实现 , 当对象小于256K时有该层直接分配内存;
第3层是最上层 , 也就是我们对Python对象的直接操作;
在 C 中如果频繁的调用 malloc 与 free 时,是会产生性能问题的.再加上频繁的分配与释放小块的内存会产生内存碎片. Python 在这里主要干的工作有:
如果请求分配的内存在1~256字节之间就使用自己的内存管理系统,否则直接使用 malloc.
这里还是会调用 malloc 分配内存,但每次会分配一块大小为256k的大块内存.
经由内存池登记的内存到最后还是会回收到内存池,并不会调用 C 的 free
释放掉.以便下次使用.对于简单的Python对象 , 例如数值、字符串 , 元组(tuple不允许被更改)采用的是复制的方式(深拷贝?) , 也就是说当将另
一个变量B赋值给变量A时 , 虽然A和B的内存空间仍然相同 , 但当A的值发生变化时 , 会重新给A分配空间 , A和B的地址变得不再相同;
而对于像字典(dict) , 列表(List)等 , 改变一个就会引起另一个的改变 , 也称之为浅拷贝:
附录:
引用计数增加
1.对象被创建:x=4
2.另外的别人被创建:y=x
3.被作为参数传递给函数:foo(x)
4.作为容器对象的一个元素:a=[1,x,’33’]
引用计数减少
1.一个本地引用离开了它的作用域 。比如上面的foo(x)函数结束时 , x指向的对象引用减1 。
2.对象的别名被显式的销毁:del x ;或者del y
3.对象的一个别名被赋值给其他对象:x=789
- 庄家洗盘的目的是什么?
- 煮梨水放冰糖好不好
- 国内做财务机器人的公司有哪些?
- 山楂泡水是干的好还是新鲜的好
- 在A股里,真正的人工智能龙头除了科大讯飞,还有哪几个?
- 新鲜山楂怎么吃最好
- 庄家洗盘的手法怎么能判断出来?
- 您知道全球人工智能Al机器人行业里面的四大家族吗?您个人怎么去评价这四家公司?
- 过期的化妆品可以怎么处理
- 国内有哪些优秀的AI电销机器人开发公司?
