python的垃圾回收机制

进程空间

进程运行时需要在内核中占据一段内存空间,用以存储程序和数据。

每个进程空间分布如下所示:

进程空间的结构

  • text段:
    代码段(code segment/text segment)通常是指用来存放程序执行代码的一块内存区域。在代码段中,也有可能包含一些只读的常数变量,例如字符串常量等。
  • data段:
    数据段(data segment)通常用来存放程序中已初始化的全局变量数据段属于静态内存分配。
  • bss段:
    bss(Block Started by Symbol) 通常用来存放程序中未初始化的全局变量。bss段属于静态内存分配。
  • 堆(heap):
    堆用于存放动态变量,它的大小并不固定,可动态扩张或缩减。
    主要由程序员手工分配:
      当进程调用malloc等函数分配内存时,新分配的内存就被动态添加到堆上;
      当利用free等函数释放内存时,被释放的内存从堆中被剔除。
  • 栈(stack):
    存储局部、临时变量,函数调用时,存储函数的返回指针,用于控制函数的调用和返回,在程序块开始时自动分配内存,结束时自动释放内存,主要由编译器自动管理。
      在函数被调用时,其参数会被压入发起调用的进程栈中,并且待到调用结束后,函数的返回值也会被存放回栈中。

注:堆和栈的区别参见末尾附图1.

可能产生的问题

内存泄漏
当程序中使用malloc的时候,堆(heap)会向上增长,其增长的部分就成为malloc从内存中分配的空间。malloc开辟的空间会一直存在,直到程序员手工用free系统调用来释放,或者进程结束。

内存泄漏(memory leakage), 就是指我们没有释放不再使用的堆空间,导致堆不断增长,而内存可用空间不断减少。

栈溢出
栈和堆的大小则会随着进程的运行增大或者变小。当栈和堆增长到两者相遇时候,也就是内存空间图中stack和heap之间的可用内存区域完全耗尽时,进程会出现栈溢出(stack overflow)的错误,导致进程终止。

垃圾回收机制(Garbage-Collection)

由上文可知,进程的内存管理是十分重要的,内存需要被合理分配使得进程能够正常运行,避免出现内存泄漏、栈溢出等异常情况。

内存空间是有限的,不能一味地分配内存,需要有人负责回收分配出去的内存空间,如果交由程序员手动进行内存管理,程序员就比较累,没法完全专注于业务逻辑的实现,影响开发效率,而且手动管理内存是纯技术活,人工错误很常见,这就有了垃圾回收机制(Garbage-Collection),程序员只要专注于业务逻辑的实现,尽管用内存,不必关心内存的回收。

垃圾回收机制(Garbage-Collection)的职能:

识别那些垃圾对象,从垃圾对象那回收内存。并分配给新生成的对象使用。

历史上几种经典的GC算法:标记-清除算法引用计数法

python采用的是引用计数机制为主,标记-清除分代回收两种机制为辅的策略

引用计数机制

  优点:简单且具备实时性:一旦一个对象的引用计数归零,内存就直接释放了。不用像其他机制等到特定时机。实时性还带来一个好处:处理回收内存的时间分摊到了平时。

  缺点:维护引用计数消耗资源,无法回收循环引用对象。

频繁的垃圾回收会降低程序执行效率,Python只会在特定条件下,自动启动垃圾回收。Python解释器保持对新创建的对象,以及因为引用计数为零而被释放掉的对象的追踪,当被分配对象的计数值与被释放对象的计数值之差达到某一阈值时便启动垃圾回收机制。

Python也采用了分代回收的策略。基于“存活时间越久的对象越不容易成为垃圾。”这一假说,若某一对象在经历多次垃圾回收后依然健在,则提升该对象的等级。对象等级一共分0,1,2三代,每次垃圾回收从0代开始,经过一定次数对0代对象的垃圾回收后,便启动对0代和1代对象的垃圾回收,1代对象经过一定次数的的垃圾回收,便启动对0代1代2代即所有对象的垃圾回收。

查看方法

import gc 
gc.set_threshold(700, 10, 5)

返回(700, 10, 10),后面的两个10是与分代回收相关的阈值,后面可以看到。700即是垃圾回收启动的阈值。

若要手动启动垃圾回收,使用gc.collect()。



附图1

时间: 2024-10-05 18:57:38

python的垃圾回收机制的相关文章

详解python的垃圾回收机制

python的垃圾回收机制 一.引子 我们定义变量会申请内存空间来存放变量的值,而内存的容量是有限的,当一个变量值没有用了(简称垃圾)就应该将其占用的内存空间给回收掉,而变量名是访问到变量值的唯一方式,所以当一个变量值没有关联任何变量名时,我们就无法再访问到该变量值了,该变量值就是一个垃圾会被python解释的垃圾回收机制自动回收 二.什么是垃圾回收机制 垃圾回收机制(简称GC)是python解释器自带的一种机制,专门用来回收不可用的变量值所占用的内存空间 三.为什么要用垃圾回收机制 程序运行过

小猿圈python之垃圾回收机制

一.前言 Python 是一门高级语言,使用起来类似于自然语言,开发的时候自然十分方便快捷,原因是Python在背后为我们默默做了很多事情,其中一件就是垃圾回收,来解决内存管理,内存泄漏的问题. 内存泄漏:当程序不停运行,有一部分对象没有作用,但所占内存没有被释放,服务器内存随时间越来越少,最终导致系统的崩溃,所以内存泄漏是一个需要重点关注的问题. Java垃圾回收 半自动 只买新的 不用管扔垃圾 Python全自动 二.python的垃圾回收机制包括引用计数.循环引用,那么我们通过什么来解决呢

python的垃圾回收机制(GC)

Hello, 大家好, 又出来冒头了. 今天想跟大家分享的是关于python的垃圾回收机制,虽然本人这会对该机制没有很深入的了解, 但是本着热爱分享的原则,还是囫囵吞枣地坐下记录分享吧, 万一分享的过程中开窍了呢.哈哈哈. 首先还是做一下概述吧: 我们都知道, 在做python的语言编程中, 相较于java, c++, 我们似乎很少去考虑到去做垃圾回收,内存释放的工作, 其实是python内部已经做了相应的回收机制, 不用我们自己操心去做内存释放.但是还是有必要了解一下.可以更加深入的了解pyt

Python之垃圾回收机制与用户交互

Python之垃圾回收机制与用户交互 垃圾回收机制 垃圾回收机制(简称GC)是Python解释器自带一种机制,专门用来回收不可用的变量值所占用的内存空间 为什么要用垃圾回收机制? 程序运行过程中会申请大量的内存空间,而对于一些无用的内存空间如果不及时清理的话会导致内存使用殆尽(内存溢出),导致程序崩溃,因此管理内存是一件重要且繁杂的事情,而python解释器自带的垃圾回收机制把程序员从繁杂的内存管理中解放出来. 垃圾回收机制原理分析 Python的GC模块主要运用了"引用计数"(ref

<转> python的垃圾回收机制

Python的GC模块主要运用了"引用计数"(reference counting)来跟踪和回收垃圾.在引用计数的基础上,还可以通过"标记-清除"(mark and sweep)解决容器对象可能产生的循环引用的问题.通过"分代回收"(generation collection)以空间换取时间来进一步提高垃圾回收的效率. 引用计数机制: python里每一个东西都是对象,它们的核心就是一个结构体:PyObject 1 typedef struct_

python中垃圾回收机制和对象变量的指向问题,深拷贝

变量.对象和引用 一个变量也就是变量名,当代码第一次赋值时就创建了他,之后的赋值将改变已创建的变量名的值. 变量类型,变量中没有类型之说,类型存在于对象中,变量只是在一个特定的时间对对象的引用. 变量使用,变量出现在表达式中会立即被对象所替代,所有变量在使用前就应该对其明确赋值. 例如 a = 3 为例 python将执行3个步骤完成这个请求 1.创建一个对象来代表3 2.创建一个一个变量a,如果他还没创建的话, 3.将变量与新的对象相连接 变量-引用-对象 对象的垃圾回收机制 当变量名被赋予了

简单理解python的垃圾回收机制

关键词:垃圾回收.引用计数.分代回收.标记-清除 前言:理解python中变量的定义:抽象理解python中变量的定义过程 1.垃圾回收机制的基本组成: python采用的是以引用计数为主,以分代回收和标记清除为辅的垃圾回收机制 2.详细分析垃圾回收机制: (1)首先是引用计数: 在python中,每创建一个对象,那么python解释器会自动为其设置一个特殊的变量,这个变量称为引用计数(初始值默认是1).一旦有一个新变量指向这个对象,那么这个引用计数的值就会加1.如果引用计数的值为0.那么pyt

python基础-垃圾回收机制

垃圾回收 Python中的垃圾回收是以引用计数为主,分代收集为辅.引用计数的缺陷是循环引用的问题. 引用计数 原理:当一个对象的引用被创建或者复制时,对象的引用计数加1:当一个对象的引用被销毁时,对象的引用计数减1,当对象的引用计数减少为0时,就意味着对象已经再没有被使用了,可以将其内存释放掉. 优点:引用计数有一个很大的优点,即实时性,任何内存,一旦没有指向它的引用,就会被立即回收,而其他的垃圾收集技术必须在某种特殊条件下才能进行无效内存的回收. 缺点:但是它也有弱点,引用计数机制所带来的维护

python的垃圾回收机制 继承的顺序C3算法

Python垃圾回收    -- 引用计数        -- Python为每个对象维护一个引用计数        -- 当引用计数为0的 代表这个对象为垃圾    -- 标记清除        -- 解决孤立的循环引用        -- 标记根节点和可达对象        -- 不可达视为垃圾    -- 分代回收        -- 解决标记清除的效率问题        -- 0代 1代 2代        -- 阈值 (700,10,10)        -- 当调用c的接口开辟内存和