参考链接: Python中的垃圾回收

Python的垃圾回收机制

Python的垃圾回收机制有两种(也可以说一种:叫引用计数): 一是引用计数, 二是隔代回收.

引用计数

引用计数原理: 当数据的引用数变成0的时候,python解释器就认为这个数据是垃圾,进行垃圾回收,释放空间.

分代回收

分代回收是用来解决交叉引用(循环引用),并增加数据回收的效率. 原理: 通过对象存在的时间不同,采用不同的算法来 回收垃圾. 形象的比喻, 三个链表,零代链表上的对象(新创建的对象都加入到零代链表),引用数都是一,每增加一个指针,引用加一,随后python会检测列表中的互相引用的对象,根据规则减掉其引用计数. GC算法对链表一的引用减一,引用为0的,清除,不为0的到链表二,链表二也执行GC算法,链表三一样. 存在时间越长的数据,越是有用的数据.

标记清除

为什么python没有标记清除机制,

因为python的标记就是引用数,是模仿Ruby的标记清除机制,为什么Ruby要用标记清除机制,因为Ruby在代码开始执行之前就已经创建了成百上千个对象,对有指针的对象进行标记(这个标记是Ruby解释器制作的),没有指针的对象进行清除,并送回可用列表中,从而节约计算机资源.

标记清除是Ruby的垃圾回收机制,标记(通过M标记)可达的数据, 会清除不带M标记的数据.

JAVA中

如何判断对象是否存活

引用计数法

给对象添加一个引用计数器,每当有一个地方引用它时,计数器值就加1,如果引用失效,计数器值减1,所以当该计数器的值为0时,就表示该对象可以被回收了。但是存在两个对象之间相互循环引用的问题。

可达性分析算法

通过一系列的称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索的路径称为引用链,当一个对象到“GC Roots”没有任何引用链相连的话,也就是GC Roots到这个对象不可达时,证明此对象已经不可用,可以被回收了。

二次标记

在可达性分析算法中被判断是对象不可达时不一定会被垃圾回收机制回收,因为要真正宣告一个对象的死亡,必须经历两次标记的过程。如果发现对象不可达时,将会进行第一次标记,此时如果该对象调用了finalize()方法,那么这个对象会被放置在一个叫F-Queue的队列之中,如果在此队列中该对象没有成功拯救自己(拯救自己的方法是该对象有没有被重新引用),那么GC就会对F-Queue队列中的对象进行小规模的第二次标记,一旦被第二次标记的对象,将会被移除队列并等待被GC回收,所以finalize()方法是对象逃脱死亡命运的最后一次机会。

垃圾回收算法

标记—清除算法

首先标记出需要回收的对象,在标记完成后进行统一的回收(标记即二次标记的过程)。此算法有两个不足:一是效率问题,标记和清除两个过程效率都不高;二是空间问题,标记清除后会产生大量不连续的内存碎片,内存空间碎片太多的话会导致以后程序在运行中想要分配较大对象的时候,无法找到一块连续的内存空间而导致不得不进行又一次的GC回收(后续的垃圾回收算法都是基于此算法进行改进的)。

标记—清除算法

复制算法

把内存按容量划分为大小相等的两块区域,每次只使用其中的一块,当这一块的内存空间用完了,就把还存活的对象复制到另一块内存中去,然后把已经使用的过的内存空间一次性清理掉。这样每次都是对半个内存区域进行GC回收,并不会产生内存碎片,但是代价是把内存缩小了一半,效率比较低。

复制算法

标记—整理算法

标记算法一样,区别是清除的时候会把所有存活的对象向一端移动(向上和向左),然后清除掉端边界以外的内存。

标记—整理算法

分代收集算法

根据对象存活周期的不同将内存划分为几块(新生代或老生代),然后根据每个年代的特点采用最合适的收集算法。比如在新生代中,每次都有大量对象死去,就选择复制算法;而在老生代中对象的生存率高,没有额外的空间为它进行分配担保,所以采用标记—清除算法或者标记—整理算法来进行回收

垃圾回收器

CMS收集器

CMS收集器是一种以获取最短回收停顿时间为目标的垃圾收集器,是基于“标记——清除”算法实现的,其回收过程主要分为四个步骤:

(1)初始标记:标记一下GC Roots能直接关联到的对象,速度很快; (2)并发标记:进行GC Roots Tracing的过程,也就是标记不可达的对象,相对耗时; (3)重新标记:修正并发标记期间因用户程序继续运作导致的标记变动,速度比较快; (4)并发清除:对标记的对象进行统一回收处理,比较耗时;

由于初始标记和重新标记速度比较快,其它工作线程停顿的时间几乎可以忽略不计,所以CMS的内存回收过程是与用户线程一起并发执行的。 初始标记和重新标记两个步骤需要Stop the world;并发标记和并发清除两个步骤可与用户线程并发执行。   “Stop the world”意思是垃圾收集器在进行垃圾回收时,会暂停其它所有工作线程,直到垃圾收集结束为止。

CMS的缺点

(1)对CPU资源非常敏感;也就是说当CMS开启垃圾收集线程进行垃圾回收时,会占用部分用户线程,如果在CPU资源紧张的情况下,会导致用户程序的工作效率下降。

(2)无法处理浮动垃圾导致又一次FULL GC的产生;由于CMS并发回收垃圾时用户线程同时也在运行,伴随用户线程的运行自然会有新的垃圾产生,这部分垃圾出现在标记过程之后,CMS无法在当次收集过程中进行回收,只能在下一次GC时在进行清除。所以在CMS运行期间要确保内存中有足够的预留空间用来存放用户线程的产生的浮动垃圾,不允许像其它收集器一样等到老年代区完全填满了之后再进行收集;那么当内存预留的空间不足时就会产生又一次的FULL GC来释放内存空间,由于是通过Serial Old收集器进行老年代的垃圾收集,所以导致停顿的时间变长了(系统有一个阈值来触发CMS收集器的启动,这个阈值不允许太高,太高反而导致性能降低)。

(3)标记——清除算法会产生内存碎片;如果产生过多的内存碎片时,当系统虚拟机想要再分配大对象时,会找不到一块足够大的连续内存空间进行存储,不得不又一次触发FULL GC。

G1收集器

G1收集器是一款成熟的商用的垃圾收集器,是基于“标记——整理”算法实现的,其回收过程主要分为四个步骤:

(1)初始标记:标记一下GC Roots能直接关联到的对象,速度很快; (2)并发标记:进行GC Roots Tracing的过程,也就是标记不可达的对象,相对耗时 ; (3)最终标记:修正并发标记期间因用户程序继续运作导致的标记变动,速度比较快; (4)筛选回收:首先对各个Region的回收价值和成本进行排序,根据用户所期望的GC停顿时间来制定回收计划;

G1收集器的特点

(1)并发与并行:机型垃圾收集时可以与用户线程并发运行; (2)分代收集:能根据对象的存活时间采取不同的收集算法进行垃圾回收; (3)不会产生内存碎片:基于标记——整理算法和复制算法保证不会产生内存空间碎片; (4)可预测的停顿:G1除了追求低停顿时间外,还能建立可预测的停顿时间模型,便于用户的实时监控;

CMS收集器与G1收集器的区别

(1)CMS采用标记——清除算法会产生空间碎片,G1采用标记——整理算法不会产生空间碎片; (2)G1可以建立可预测的停顿时间模型,而CMS则不能;

[转载] Python和java中的垃圾回收机制相关推荐

  1. 一篇文章搞定java中的垃圾回收机制面试题

    一篇文章搞定java中的垃圾回收机制面试题 任何语言在运行过程中都会创建对象,也就意味着需要在内存中为这些对象在内存中分配空间,在这些对象失去使用的意义的时候,需要释放掉这些内容,保证内存能够提供给新 ...

  2. JAVA中的垃圾回收机制以及其在android开发中的作用

    http://blog.csdn.net/xieqibao/article/details/6707519 这篇文章概述了JAVA中运行时数据的结构,以及垃圾回收机制的作用.在后半部分,描述了如何检测 ...

  3. python有向图_Python 中的垃圾回收机制

    一.概述 python采用的是引用计数机制为主,标记-清除和分代收集(隔代回收)两种机制为辅的策略. 现在的高级语言如java,c#等,都采用了垃圾收集机制,而不再是c,c++里用户自己管理维护内存的 ...

  4. 第八章软件构造的性能——构造性能的度量、原则与方法(java中的垃圾回收机制及算法)

    这节内容真的是多到炸裂,而且全都是概念,不过很挺有用的,学完这节会对内存管理有一个比较深的理解和认识,就是--这也太多了--嘤嘤嘤T_T 1.性能度量(performance metrics) 第一点 ...

  5. 《对Java的分析总结》-Java中的垃圾回收机制中的标记-清除算法 (五)

    标记-清除算法 标记-清除算法(mark-sweep 1 标记-清除算法 回收过程描述 类别 描述 mutator 设置 collector 收集 mutator roots mutator根对象 1 ...

  6. Java Jvm 中的垃圾回收机制中的思想与算法 《对Java的分析总结》-四

    Java中的垃圾回收机制中的思想与算法 <对Java的分析总结>-四 垃圾回收机制 中的思想与算法 引用计算法 给对象中添加一个引用计数器,每当一个地方引用它的时候就将计数器加1,当引用失 ...

  7. Java中的垃圾回收与对象生命周期

    转载自   Java中的垃圾回收与对象生命周期 1. 垃圾回收 垃圾回收是Java程序设计中内存管理的核心概念,JVM的内存管理机制被称为垃圾回收机制. 一个对象创建后被放置在JVM的堆内存中,当永远 ...

  8. 【java虚拟机序列】java中的垃圾回收与内存分配策略

    在[java虚拟机系列]java虚拟机系列之JVM总述中我们已经详细讲解过java中的内存模型,了解了关于JVM中内存管理的基本知识,接下来本博客将带领大家了解java中的垃圾回收与内存分配策略. 垃 ...

  9. 简述python垃圾回收机制_python中的垃圾回收机制简述

    2020年12月5日21:47:35 王凯玉 python中的垃圾回收机制 引用计数 # 引用计数 引用计数是编程语言中的一中内存管理技术,可以将资源的被引用次数保存起来. 当引用计数为0时,资源将被 ...

最新文章

  1. 【c】正负数二进制表示
  2. CTS,CLS,CLR解释
  3. 小D课堂-SpringBoot 2.x微信支付在线教育网站项目实战_5-8.用户模块开发之保存微信用户信息...
  4. 在Ubuntu下看各种格式的电影──包括RMVB
  5. lammps教程:boundary命令详解
  6. Xcode8 - apploader 上传失败 - ERROR ITMS-90168: The binary you uploaded was invalid.
  7. 静态代理和动态代理的区别是什么
  8. win10系统下计算器界面变成英文的解决方法
  9. 工作内容Rshiny框架使用
  10. 主流大数据调度工具对比
  11. [Java]源码角度深入理解哈希表,手撕常见面试题
  12. 作为开发者必须知道的5个安卓应用推广方式
  13. 多个输入框失焦事件触发异常问题解决
  14. 小软件大用途!分享4款超级实用的软件,请低调收藏
  15. 标准G726音频解码和与H264视频封装为avi
  16. 怎样才能做好SNS社区网站
  17. 中国KAB创业教育网_需求分析说明书
  18. 如何用Python批量将Pdf文档转换成Word文档?
  19. grub4dos引导的U盘启动盘
  20. Buuctf[网鼎杯 2020 青龙组]AreUSerialz

热门文章

  1. 【OpenJudge7826】分苹果(小学奥数)
  2. html中加入数据库,HTML中如何连接数据库?
  3. php删除英文链接词,英语写作词汇大全:转折连接词
  4. python彩票预测与分析_130期祥子大乐透预测奖号:后区大小分析
  5. 线段树区间合并--询问某段区间内最长连续上升子序列即最长上升子串
  6. java创建对象实例的四种方式
  7. access 此程序未正确安装_一款让“微软爸爸杀不死”的数据库软件——生于1992的Access...
  8. wxpython制作表格界面_Python wxPython库使用wx.ListBox创建列表框示例
  9. 数据结构—二叉树,满二叉树、完全二叉树、二叉树的性质(思维导图)
  10. 计算机网络—计算机网络核心