Python垃圾回收机制

1. 内存泄露

  • 程序本身没有设计好,导致程序未能释放已不再使用的内存
  • 代码在分配了某段内存后,因为设计错误,失去了对这段内存的控制,从而造成了内存的浪费

监控python程序内存占用情况,psutil库

import os
import psutil # 显示当前程序占用内存大小
def show_memory_info(hint):
pid = os.getpid() # 获取当前进程号
p = psutil.Process(pid)
info = p.memory_info()
memory = info.rss / 1024. / 1024
print(f"{hint} 内存用了:{memory}MB")

查看对象占用内存大小

import sys
a = [i for i in range(10000)]
memory = sys.getsizeof(a) / 1024
print(f"内存用了:{memory}KB")
# 内存用了:85.578125KB

2. Python什么时候启动垃圾回收机制?

2.1 计数引用

python中一切皆对象,所看到的一切变量,本质上都是对象的一个指针,当这个对象的引用次数为0的时候,说明这个对象永不可达,成为需要被回收的垃圾

# 查看引用次数
import sys
a = []
print(sys.getrefcount(a)) # 两次引用,一次a,一次getr
def func(a):
# 四次引用,函数调用会产生两次额外的引用,一次来自函数栈,另一个是函数参数
print(sys.getrefcount(a))
func(a)
2
4
def func():
show_memory_info('初始')
a = [i for i in range(1000000)] # 列表生成式
show_memory_info('创建之后') func()
show_memory_info('结束之后') # 内存即可被释放
初始 内存用了:52.4609375MB
创建之后 内存用了:91.921875MB
结束之后 内存用了:53.80859375MB
2.2 循环引用
  • python中使用标记清除算法和分代收集,来启动针对循环引用的自动垃圾回收
  • 标记清除算法,图论中的不可达概念
  • 分代收集算法中每一代都有一个默认阈值,超过指定阈值之后就会启动垃圾回收,如果垃圾回收启动太频繁,会造成程序性能低下,分代收集为了提高性能,因此不立刻回收。
def func():
show_memory_info('初始')
a = [i for i in range(1000000)] # 列表生成式
b = [i for i in range(1000000)] # 列表生成式
show_memory_info('创建之后')
a.append(b)
b.append(a) func()
show_memory_info('结束之后') # 可以看到循环引用之后,内存依旧被占用
初始 内存用了:77.125MB
创建之后 内存用了:163.8828125MB
结束之后 内存用了:163.8828125MB

显示调用gc.collect()来启动垃圾回收

import gc

def func():
show_memory_info('初始')
a = [i for i in range(1000000)] # 列表生成式
b = [i for i in range(1000000)] # 列表生成式
show_memory_info('创建之后')
a.append(b)
b.append(a) func()
# 显示调用gc.collect()来启动垃圾回收
gc.collect()
show_memory_info('结束之后')
初始 内存用了:77.609375MB
创建之后 内存用了:145.92578125MB
结束之后 内存用了:77.609375MB
问题:引用计数是0是启动垃圾回收的充要条件吗?

引用计数是其中最简单的实现,不是充要条件,只能算作充分非必要条件,循环引用需要通过不可达判定,来确定是否可以回收。python中自动回收算法包括标记清除算法和分代收集。

浅析Python垃圾回收机制!的更多相关文章

  1. python垃圾回收机制与小整数池

    python垃圾回收机制 当引用计数为0时,python会删除这个值. 引用计数 x = 10 y = x del x print(y) 10 引用计数+1,引用计数+1,引用计数-1,此时引用计数为 ...

  2. python垃圾回收机制:引用计数 VS js垃圾回收机制:标记清除

    js垃圾回收机制:标记清除 Js具有自动垃圾回收机制.垃圾收集器会按照固定的时间间隔周期性的执行. JS中最常见的垃圾回收方式是标记清除. 工作原理 当变量进入环境时,将这个变量标记为"进入 ...

  3. 简述Python垃圾回收机制和常量池的验证

    目录 通过代码验证python解释器内部使用了常量池 Python的引入 变量的引入 为什么要有变量 定义变量 常量引入 常量池引入 Python解释器 Python变量存储机制 Python垃圾回收 ...

  4. 从 CPython 源码角度看 Python 垃圾回收机制

    环状双向链表 refchain 在 Python 程序中创建的任何对象都会被放到 refchain 链表中,当创建一个 Python 对象时,内部实际上创建了一些基本的数据: 上一个对象 下一个对象 ...

  5. python垃圾回收机制的一些理解

    概览:       主要通过 引用计数来进行垃圾收集, 就是说,当一个对象没有被其他对象引用的时候,会释放掉内存.     但是会有一些循环引用的对象,通过上面的方法,是没有办法清除掉的.所以,pyt ...

  6. Python垃圾回收机制详解

    一.垃圾回收机制 Python中的垃圾回收是以引用计数为主,分代收集为辅.引用计数的缺陷是循环引用的问题. 在Python中,如果一个对象的引用数为0,Python虚拟机就会回收这个对象的内存. #e ...

  7. Python垃圾回收机制 总结

    Python 垃圾回收机制 内存管理 Python中的内存管理机制的层次结构提供了4层,其中最底层则是C运行的malloc和free接口,往上的三层才是由Python实现并且维护的,第一层则是在第0层 ...

  8. python 垃圾回收机制的思考

    一.前言 Python 是一门高级语言,使用起来类似于自然语言,开发的时候自然十分方便快捷,原因是Python在背后为我们默默做了很多事情,其中一件就是垃圾回收,来解决内存管理,内存泄漏的问题. 内存 ...

  9. Python垃圾回收机制--完美讲解!

    转自: http://www.jianshu.com/p/1e375fb40506 先来个概述,第二部分的画述才是厉害的. Garbage collection(GC) 现在的高级语言如java,c# ...

随机推荐

  1. 由软件构造引申的OOP与POP的心得体会

    在大一初学C语言的时候,所解决的问题都是一些轻量级的简单问题,当时写过一个教学管理系统.这个教学管理系统的功能很简单,思想就是“流水线”:按部就班的实现所有流程.要完成整个教学管理系统,实际上就是完成 ...

  2. 是时候拥抱.NET CORE了

    微软和社区已经做了大量艰苦的工作,使.net core成为市场上具有竞争力的框架,帮助开发人员快速开发具有最佳性能和可扩展性的强大应用程序.做的最棒的事情使.net framework开发人员不需要任 ...

  3. 重学 Java 设计模式:实战享元模式「基于Redis秒杀,提供活动与库存信息查询场景」

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 程序员‍‍的上下文是什么? 很多时候一大部分编程开发的人员都只是关注于功能的实现,只 ...

  4. PowerBuilder中调用NPOI进行Excel导出格式设置示例

    // 功能 :新建excel带边框的单元格,格式为数字并显示为美元货币 // 参数 :ai_row,行号:ai_col,列号 // 返回值 :true/false // 作者 :潮崖之飔 // 日期 ...

  5. java中HashMap原理?

    参考:https://www.cnblogs.com/yuanblog/p/4441017.html(推荐) https://blog.csdn.net/a745233700/article/deta ...

  6. opencv C++极坐标变换

    #include<opencv2/core/core.hpp> #include<opencv2/highgui/highgui.hpp> #include<opencv ...

  7. 甜咸粽子党大战,Python爬取淘宝上的粽子数据并进行分析

    前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 爬虫 爬取淘宝数据,本次采用的方法是:Selenium控制Chrome浏览 ...

  8. JavaScript DOM 注册事件

    一个HTML是一个DOM树,每一个节点都是DOM对象,整个HTML其实也是一个DOM对象,根节点是<html>; 在HTML页面初始化的时候,JavaScript会自动帮DOM对象注册消息 ...

  9. Redis SDS 深入一点,看到更多!

    1.什么是SDS? Redis 自定的字符串存储结构,关于redis,你需要了解的几点!中我们对此有过简要说明. Redis 底层是用C语言编写的,可是在字符存储上,并未使用C原生的String类型, ...

  10. 计算机网络之DNS常见攻击

    DNS欺骗 在Internet上存在的DNS服务器有绝大多数都是用bind来架设的,使用的bind版本主要为bind 4.9.5+P1以前版本和bind 8.2.2-P5以前版本.这些bind有个共同 ...