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. Python常用推导式

    列表推导式: #列表推导式 #基本格式[] # 变量 = [for循环的变量 for循环一个可迭代对象] # 变量 = [i for i in 可迭代对象 if 条件] 条件为true才进行appen ...

  2. HDU-3033 I love sneakers! 题解

    题目大意 有 n 个物品,分成了 k 组,每个物品有体积和价值,把 n 个物品放到容量为 V 的背包中,保证每组至少放一件,求能获得的最大价值,如果不能实现,输出"Impossible&qu ...

  3. kafka能做什么?kafka集群配置 (卡夫卡 大数据)

    什么是Kafka 官网介绍: 几个概念: 详细介绍 : 操作kafka: kafka集群 消息测试 问题检测 什么是Kafka 官网介绍: ApacheKafka是一个分布式流媒体平台.这到底是什么意 ...

  4. (数据科学学习手札87)利用adjustText解决matplotlib文字标签遮挡问题

    本文示例代码.数据已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 1 简介 在进行数据可视化时我们常常需要在可视化作品 ...

  5. flex弹性模型

    flex模型是w3c最新提出的一种盒子模型,很好的解决了普通模型的一些弊端. 一.比较两种盒子模型: demo: 给div添加边框,观察他们的区别 <body> <div class ...

  6. FastStone+ImageReady+Kutools plus导入图片到Excel单元格

    先前打算自己做一个也附带训练下,发现有下面方法也好. 1)做帮助文档时需要一种格式(需要将图片导入到Excel中时,假如是按此法归类汇总) 2)FastStone滚动截图       粘贴到Photo ...

  7. 这一次搞懂SpringMVC原理

    @ 目录 前言 正文 请求入口 组件初始化 调用Controller 参数.返回值解析 总结 前言 前面几篇文章,学习了Spring IOC.Bean实例化过程.AOP.事务的源码和设计思想,了解了S ...

  8. linux下操作memcache的操作命令

    1.连接memcache linux下一般使用telnet连接memcache服务 [root@localhost ~]# telnet 127.0.0.1 11266 Trying 127.0.0. ...

  9. Java对MongoDB的CRUD

    https://blog.51cto.com/aiilive/1339058 MongoDB提供的Java操作API可以说是对Mongo数据库命令的Java翻译,熟悉Mongo命令,熟悉Java操作数 ...

  10. java 基础 流程控制

    鄙人不才,基础不好,趁着闲时简单学习一下,仅作学习分享,如有不正确地方还请各位看客不吝指出. Java流程主要可以分为: 顺序(可以按照正常顺序一步步往下运行的) 选择(三元操作符[?:];if el ...