浅析Python垃圾回收机制!
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垃圾回收机制!的更多相关文章
- python垃圾回收机制与小整数池
python垃圾回收机制 当引用计数为0时,python会删除这个值. 引用计数 x = 10 y = x del x print(y) 10 引用计数+1,引用计数+1,引用计数-1,此时引用计数为 ...
- python垃圾回收机制:引用计数 VS js垃圾回收机制:标记清除
js垃圾回收机制:标记清除 Js具有自动垃圾回收机制.垃圾收集器会按照固定的时间间隔周期性的执行. JS中最常见的垃圾回收方式是标记清除. 工作原理 当变量进入环境时,将这个变量标记为"进入 ...
- 简述Python垃圾回收机制和常量池的验证
目录 通过代码验证python解释器内部使用了常量池 Python的引入 变量的引入 为什么要有变量 定义变量 常量引入 常量池引入 Python解释器 Python变量存储机制 Python垃圾回收 ...
- 从 CPython 源码角度看 Python 垃圾回收机制
环状双向链表 refchain 在 Python 程序中创建的任何对象都会被放到 refchain 链表中,当创建一个 Python 对象时,内部实际上创建了一些基本的数据: 上一个对象 下一个对象 ...
- python垃圾回收机制的一些理解
概览: 主要通过 引用计数来进行垃圾收集, 就是说,当一个对象没有被其他对象引用的时候,会释放掉内存. 但是会有一些循环引用的对象,通过上面的方法,是没有办法清除掉的.所以,pyt ...
- Python垃圾回收机制详解
一.垃圾回收机制 Python中的垃圾回收是以引用计数为主,分代收集为辅.引用计数的缺陷是循环引用的问题. 在Python中,如果一个对象的引用数为0,Python虚拟机就会回收这个对象的内存. #e ...
- Python垃圾回收机制 总结
Python 垃圾回收机制 内存管理 Python中的内存管理机制的层次结构提供了4层,其中最底层则是C运行的malloc和free接口,往上的三层才是由Python实现并且维护的,第一层则是在第0层 ...
- python 垃圾回收机制的思考
一.前言 Python 是一门高级语言,使用起来类似于自然语言,开发的时候自然十分方便快捷,原因是Python在背后为我们默默做了很多事情,其中一件就是垃圾回收,来解决内存管理,内存泄漏的问题. 内存 ...
- Python垃圾回收机制--完美讲解!
转自: http://www.jianshu.com/p/1e375fb40506 先来个概述,第二部分的画述才是厉害的. Garbage collection(GC) 现在的高级语言如java,c# ...
随机推荐
- Windows10 搭建 ElasticSearch 集群服务
一.前言 集群的搭建需要多台机器,之前我使用 ubuntu 16.04 搭建过 hadoop 的单机模式和分布式模式,这个今后会写,今天先写一篇使用 < Windows10 搭建 Elastic ...
- Cookie 与 SessionID 的本质
当用户首次访问服务器的时候,服务器为每个用户单独创建一个 Session 对象,并分配一个新的 SessionID,此时 SessionID 通过 Cookie 保存在用户端. 当用户再次访问服务器的 ...
- 别再写一摞if-else了!再写开除!两种设计模式带你消灭它!
代码洁癖狂们!看到一个类中有几十个if-else是不是很抓狂? 设计模式学了用不上吗?面试的时候问你,你只能回答最简单的单例模式,问你有没有用过反射之类的高级特性,回答也是否吗? 这次就让设计模式(模 ...
- 基于移动最小二乘法的点云曲面拟合(python)
1.移动最小二乘法介绍 为了更好地对数据量大且形状复杂的离散数据进行拟合,曾清红等人[1]开发出一种新的算法——移动最小二乘法.这种新的最小二乘算法为点云数据的处理提供了新的方法.使用点云数据拟合曲面 ...
- matlab 梯度法(最速下降法)
norm(A,p)当A是向量时norm(A,p) Returns sum(abs(A).^zhip)^(/p), for any <= p <= ∞.norm(A) Returns nor ...
- 如何从二进制文件中读取int型序列
使用的主要函数是int.from_bytes 代码如下: f = open('./T26.dat', 'rb') for i in range(20): A = f.read(2) A = int.f ...
- YII2.0安装教程,数据库配置前后台
1.首先下载yii-advanced-app-2.0.6.tgz 我本地服务用的是Apache 2.解压到E:\wamp\www\yii2目录下面将目录advanced下所有文件剪切到 E:\wamp ...
- cc32b_demo-32dk2j_cpp_纯虚函数与抽象类2-txwtech
cc32b_demo-32dk2j_cpp_纯虚函数与抽象类2-txwtech //纯虚函数是用来继承用的//纯虚函数//抽象类-抽象数据类型//*任何包含一个或者多个纯虚函数的类都是抽象类//*不要 ...
- 这篇文章,我们来谈一谈Spring中的属性注入
本系列文章: 读源码,我们可以从第一行读起 你知道Spring是怎么解析配置类的吗? 配置类为什么要添加@Configuration注解? 谈谈Spring中的对象跟Bean,你知道Spring怎么创 ...
- opencv C++矩阵操作
int main(){ cv::Mat src1=(cv::Mat_<float>(2,3)<<1,2,3,4,5,6); cv::Mat src2=(cv::Mat_< ...