
正文
python函数引用计数,python中怎么计数
提示:扫一扫查出行【扫一扫了解最新限行尾号】
复制提示
python怎么进行内存管理的?
一、对象的引用计数机制
python内部使用引用计数,来保持追踪内存中的对象,所有对象都有引用计数
引用计数增加的情况:
1. 一个对象分配一个新名称
2. 将其放入一个容器中
引用计数减少的情况:
1. 使用del语句对对象别名显示的销毁
2. 引用超出作用域或被重新赋值
sys.getrefcount()函数可以获得对象的当前引用计数
多数情况下,引用计数比你猜测的要大得多。对于不可变数据(如数字和字符串),解释器会在程序的不同部分共享内存,以便节约内存。
二、垃圾回收
当一个对象的引用计数归零时,它将被垃圾收集机制处理掉。当两个对象a 和b 相互引用时,del语句可以减少a和b的引用次数,并销毁用于引用底层对象的名称。然而由于每个对象都包含一个对其他对象的应用,因此引用计数不会归零,对象也不会销毁。(从而导致内存泄漏)。为解决这一问题,解释器会定期执行一个循环检测器,搜索不可访问对象的循环并删除它们。
三、内存池机制
python提供了对内存的垃圾收集机制,但是它将不用的内存放到内存池而不是返回给操作系统。
1. Pymalloc机制。为了加速python的执行效率,python引入了一个内存池机制,用于管理对小块内存的申请和释放。
2. python中所有小于256个字节的对象都使用pymalloc实现的分配器,而大的对象则使用系统的malloc。
3. 对于python对象,如整数,浮点数和list,都有其独立的私有内存池,对象间不共享它们的内存池。也就是说如果你分配又释放了大量的整数,用于缓存这些整数的内存就不能再分配给浮点数。
相关问答
Q1: python 为什么调用函数会令引用计数+2
python自己没有array这个数据结构。
据我所知
array是python的numpy
工具包
定义的。
python的list就是常说的列表。
array和list主要的不同是,因为numpy是一个
数值计算
工具包,numpy的很多函数是可以直接在array上使用的,但不能用在list上。
Q2: Python如何进行内存管理
Python的内存管理,一般从以下三个方面来说:
1)对象的引用计数机制(四增五减)
2)垃圾回收机制(手动自动,分代回收)
3)内存池机制(大m小p)
1)对象的引用计数机制
要保持追踪内存中的对象,Python使用了引用计数这一简单的技术。sys.getrefcount(a)可以查看a对象的引用计数,但是比正常计数大1,因为调用函数的时候传入a,这会让a的引用计数+1
2)垃圾回收机制
吃太多,总会变胖,Python也是这样。当Python中的对象越来越多,它们将占据越来越大的内存。不过你不用太担心Python的体形,它会在适当的时候“减肥”,启动垃圾回收(garbage
collection),将没用的对象清除
从基本原理上,当Python的某个对象的引用计数降为0时,说明没有任何引用指向该对象,该对象就成为要被回收的垃圾了
比如某个新建对象,它被分配给某个引用,对象的引用计数变为1。如果引用被删除,对象的引用计数为0,那么该对象就可以被垃圾回收。
然而,减肥是个昂贵而费力的事情。垃圾回收时,Python不能进行其它的任务。频繁的垃圾回收将大大降低Python的工作效率。如果内存中的对象不多,就没有必要总启动垃圾回收。
所以,Python只会在特定条件下,自动启动垃圾回收。当Python运行时,会记录其中分配对象(object
allocation)和取消分配对象(object deallocation)的次数。当两者的差值高于某个阈值时,垃圾回收才会启动。
我们可以通过gc模块的get_threshold()方法,查看该阈值。
3)内存池机制
Python中有分为大内存和小内存:(256K为界限分大小内存)
1、大内存使用malloc进行分配
2、小内存使用内存池进行分配
python中的内存管理机制都有两套实现,一套是针对小对象,就是大小小于256K时,pymalloc会在内存池中申请内存空间;当大于256K时,则会直接执行系统的malloc的行为来申请内存空间。







