欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

浅谈python的内存管理机制

程序员文章站 2022-04-11 17:07:22
...

python的内存管理机制大致可以从三个方面来讲:

  1. 引用计数
  2. 垃圾回收
  3. 内存池机制

引用计数

python内部使用引用计数,来保持追踪内存中的对象,
Python内部记录了对象有多少个引用,即引用计数,当对象被创建时就创建了一个引用计数,
当对象不再需要时,这个对象的引用计数为0时,它被垃圾回收。
查看对象的引用计数:sys.getrefcount()

引用计数增加:

  • 对象被创建:x=4
  • 另外的别人被创建:y=x
  • 被作为参数传递给函数:foo(x)
  • 作为容器对象的一个元素:a=[1,x,‘33’]

引用计数减少:

  • 一个本地引用离开了它的作用域。比如上面的foo(x)函数结束时,x指向的对象引用减1
  • 对象的别名被显式的销毁:del x ;或者del y
  • 对象的一个别名被赋值给其他对象:x=789
  • 对象从一个窗口对象中移除:myList.remove(x)
  • 窗口对象本身被销毁:del myList,或者窗口对象本身离开了作用域

垃圾回收

garbage collection,将没用的对象清除。
1、它会去检查那些引用计数为0的对象,然后清除其在内存的空间。
当然除了引用计数为0的会被清除,还有一种情况也会被垃圾收集器清掉:
当两个对象相互引用时,他们本身其他的引用已经为0了。
2、垃圾回收机制还有一个循环垃圾回收器, 确保释放循环引用对象
(a引用b, b引用a, 导致其引用计数永远不为0)

垃圾回收机制:

  • 引用计数:引用计数也是一种垃圾收集机制, 而且也是一种最直观, 最简单的垃圾收集技术.当python某个对象的引用计数降为 0 时, 说明没有任何引用指向该对象, 该对象就成为要被回收的垃圾了.(如果出现循环引用的话, 引用计数机制就不再起作用了)
  • 标记清除:如果两个对象的引用计数都为 1 , 但是仅仅存在他们之间的循环引用,那么这两个对象都是需要被回收的, 也就是说 它们的引用计数虽然表现为非 0 , 但实际上有效的引用计数为 0 ,.所以先将循环引用摘掉, 就会得出这两个对象的有效计数
  • 分代回收:从前面“标记-清除”这样的垃圾收集机制来看,这种垃圾收集机制所带来的额外操作实际上与系统中总的内存块的数量是相关的,当需要回收的内存块越多时,垃圾检测带来的额外操作就越多,而垃圾回收带来的额外操作就越少;反之,当需要回收的内存块越少时,垃圾检测就将比垃圾回收带来更少的额外操作
    注意:
  • 垃圾回收时,python不能进行其他的任务,频繁的垃圾回收将大大降低python的工作效率
  • python只会在特定条件下自动启动垃圾回收(垃圾对象少就没必要回收)
  • 当python运行时,会记录其中分配对象(object allocation)和取消分配对象(object deallocation)的次数。当两者的差值高于某个阈值时,垃圾回收才会启动

内存池机制

Python提供了对内存的垃圾收集机制,但是它将不用的内存放到内存池而不是返回给操作系统。
Python中有分为大内存和小内存:(256K为界限分大小内存)
- 大内存使用malloc进行分配
- 小内存使用内存池进行分配

python的内存池金字塔:
浅谈python的内存管理机制

  • -1,-2层主要有操作系统进行操作
  • 第0层是C中的malloc,free等内存分配和释放函数进行操作
  • 第1层和第2层是内存池,有Python的接口函数PyMem_Malloc函数实现,当对象小于256K时有该层直接分配内存
  • 第3层是最上层,也就是我们对Python对象的直接操作

参考:

  1. python内存管理机制
  2. python的内存管理机制(zz)
  3. python面试题之Python是如何进行内存管理的