Python的内存管理
文章目录
- 1. **内存管理的基本原理**
- (1)动态内存分配
- (2)引用计数机制
- 2. **垃圾回收(Garbage Collection, GC)机制**
- (1)循环引用问题
- (2)垃圾回收器的作用
- 3. **内存池机制**
- (1)小对象 vs 大对象
- (2)`PyObject` 内存池
- 4. **内存泄漏的预防和优化**
- (1)循环引用
- (2)全局变量的滥用
- (3)大对象的重复使用
- 5. **内存调试工具**
- (1)`gc` 模块
- (2)`sys` 模块
- (3)`tracemalloc` 模块
- 6. **Python 的内存管理优势**
- 总结
Python 的内存管理机制是 Python 解释器的核心特性之一,它通过多种方式来高效地分配、使用和回收内存,从而确保程序稳定运行。以下是 Python 内存管理的关键概念及原理:
1. 内存管理的基本原理
Python 的内存管理由以下几个部分组成:
(1)动态内存分配
- Python 中所有变量和对象都是通过动态内存分配的。也就是说,程序运行时才会为变量或对象分配内存。
- Python 的对象(如列表、字符串、字典等)存储在堆(Heap)中,而变量名作为引用绑定到这些对象。
(2)引用计数机制
- Python 采用引用计数来跟踪一个对象的使用情况。
- 每个对象都有一个计数器
ref_count,表示当前有多少个引用指向该对象。当引用计数降为 0 时,Python 会自动回收该对象占用的内存。
示例:引用计数
import sysa = [1, 2, 3] # 创建一个列表对象
print(sys.getrefcount(a)) # 输出: 2(一个是 a,另一个是 getrefcount 函数的临时引用)b = a # b 引用同一个对象
print(sys.getrefcount(a)) # 输出: 3del a # 删除 a 的引用
print(sys.getrefcount(b)) # 输出: 2del b # 删除 b 的引用,引用计数降为 0,此时对象被回收
2. 垃圾回收(Garbage Collection, GC)机制
当对象的引用计数降为 0 时,内存会被释放。但是,Python 的内存管理不仅依赖引用计数,还引入了垃圾回收机制来处理循环引用的问题。
(1)循环引用问题
当两个对象互相引用时,尽管它们已经失去了其他外部引用,其引用计数仍不为 0,从而导致内存泄漏。
示例:循环引用
class Node:def __init__(self, value):self.value = valueself.next = Nonen1 = Node(1)
n2 = Node(2)
n1.next = n2
n2.next = n1 # 循环引用del n1
del n2
# 即使删除了对象,循环引用导致引用计数始终大于 0
(2)垃圾回收器的作用
Python 的垃圾回收器会定期扫描对象图,识别那些存在循环引用但不再被使用的对象,并释放它们的内存。
- 垃圾回收触发条件:
- 手动调用:可以通过
gc模块的gc.collect()方法手动触发。 - 自动触发:垃圾回收器会在一定条件下自动运行,比如内存分配达到阈值时。
- 手动调用:可以通过
示例:使用垃圾回收模块
import gc# 查看当前垃圾回收器的状态
print(gc.isenabled()) # 输出: True(自动垃圾回收默认开启)# 禁用垃圾回收
gc.disable()# 手动触发垃圾回收
gc.collect()
3. 内存池机制
Python 对小对象的内存分配进行了优化,通过内存池机制减少了频繁的系统内存分配和释放的开销。
(1)小对象 vs 大对象
- 小对象(<256字节):
- Python 使用了专门的内存池(如
PyObject池)管理小对象。 - 这些小对象会被分配到固定大小的内存块中,释放后会被重复利用。
- Python 使用了专门的内存池(如
- 大对象(>=256字节):
- 大对象直接由操作系统分配和释放,不使用内存池。
(2)PyObject 内存池
- Python 提供了一个分层的内存分配机制,核心是
PyObject_Malloc,用来管理小对象。 - 例如,整数、字符串等常见小对象会被缓存起来重复使用,以提高性能。
示例:整数对象的缓存
a = 10
b = 10
print(id(a), id(b)) # 两个变量共享同一个整数对象c = 1000
d = 1000
print(id(c), id(d)) # 对于较大的整数,可能会创建不同的对象
4. 内存泄漏的预防和优化
尽管 Python 提供了自动内存管理机制,但在某些情况下仍可能发生内存泄漏。以下是常见原因及优化建议:
(1)循环引用
- 问题:如果两个对象互相引用且无法被垃圾回收器识别,可能导致内存泄漏。
- 解决方案:使用弱引用(
weakref模块)来打破循环引用。
示例:使用弱引用
import weakrefclass Node:def __init__(self, value):self.value = valueself.next = Nonen1 = Node(1)
n2 = Node(2)
n1.next = weakref.ref(n2) # 使用弱引用打破循环
n2.next = weakref.ref(n1)
(2)全局变量的滥用
- 问题:全局变量生命周期长,可能导致内存占用过高。
- 解决方案:避免滥用全局变量,将变量局部化。
(3)大对象的重复使用
- 问题:频繁创建大对象(如大量数据的列表或字典)占用内存过高。
- 解决方案:尽量复用已有对象,或使用生成器、迭代器等实现延迟计算。
5. 内存调试工具
为了定位和优化程序中的内存问题,Python 提供了一些调试工具:
(1)gc 模块
- 检查当前未被回收的对象:
import gc
print(gc.garbage) # 输出未被回收的对象列表
(2)sys 模块
- 查看对象的引用计数:
import sys
a = [1, 2, 3]
print(sys.getrefcount(a)) # 输出引用计数
(3)tracemalloc 模块
- 用于跟踪内存分配,帮助定位内存使用的高峰和来源:
import tracemalloctracemalloc.start()# 执行一些代码
a = [i for i in range(100000)]snapshot = tracemalloc.take_snapshot()
top_stats = snapshot.statistics('lineno')for stat in top_stats[:10]:print(stat)
6. Python 的内存管理优势
- 自动化管理:开发者无需手动管理内存分配和释放,大幅降低了内存管理的复杂性。
- 高效:通过引用计数和垃圾回收机制相结合,避免了内存泄漏。
- 优化小对象性能:内存池机制显著提升了小对象的分配效率。
总结
Python 的内存管理以引用计数为基础,辅以垃圾回收机制来解决循环引用问题,同时通过内存池机制优化小对象的性能。尽管 Python 的内存管理大多是自动化的,我们仍需在某些场景下注意优化代码(如避免循环引用、合理使用生成器等),以提高程序的内存使用效率和稳定性。
相关文章:
Python的内存管理
文章目录 1. **内存管理的基本原理**(1)动态内存分配(2)引用计数机制 2. **垃圾回收(Garbage Collection, GC)机制**(1)循环引用问题(2)垃圾回收器的作用 3. …...
VSCode调试
目录 C/C远程本地调试插件配置参考 C/C远程本地调试 测试源码:https://github.com/jrhee17/ssl-study 插件 Remote - SSH C/C 配置 .vscode/launch.json {"version": "0.2.0","configurations": [{"name": "afte…...
Direct Preference Optimization (DPO) 简介与流程解析:中英双语
Direct Preference Optimization (DPO) 简介与流程解析 Direct Preference Optimization (DPO) 是一种基于人类偏好的强化学习优化方法,用于训练语言模型,使其更好地满足用户需求或偏好。本文将详细介绍 DPO 的核心思想、优化流程,并结合代码…...
fisco-bcos手动搭建webase启动注意事项
手动搭建webase-front启动注意事项 Java环境变量:1.8.301时候的错误 一直提示节点连接不上,无法连接chanale端口 这是官方提供的解决办法Help wanted: solution for secp256k1 being disabled Issue #470 FISCO-BCOS/java-sdk Java SDK 2.x连接节点失败…...
ospf 的 状态机详解
OSPF(开放最短路径优先,Open Shortest Path First)协议的状态机是其核心部分之一,用于确保路由器之间的邻接关系(neighbor relationship)建立和路由信息的交换。OSPF的状态机模型由多个状态组成,…...
TP5 动态渲染多个Layui表格并批量打印所有表格
记录: TP5 动态渲染多个Layui表格每个表格设置有2行表头,并且第一行表头在页面完成后动态渲染显示内容每个表格下面显示统计信息可点击字段排序一次打印页面上的所有表格打印页面上多个table时,让每个table单独一页 后端代码示例: /*** Nod…...
spring专题笔记(六):bean的自动装配(自动化注入)-根据名字进行自动装配、根据类型进行自动装配。代码演示,通俗易懂。
目录 一、根据名字进行自动装配--byName 二、根据类型进行自动装配 byType 本文章主要是介绍spring的自动装配机制, 用代码演示spring如何根据名字进行自动装配、如何根据类型进行自动装配。代码演示,通俗易懂。 一、根据名字进行自动装配--byName Us…...
监听器listener
文章目录 监听器( listener)对Application内置对象监听的语法和配置对session内置对象监听的语法和配置 监听器( listener) 对象与对象的关系: 继承关联 tomcat一启动创建的顺序:监听器,config,application(全局初始化参数)&am…...
重温设计模式--10、单例模式
文章目录 单例模式(Singleton Pattern)概述单例模式的实现方式及代码示例1. 饿汉式单例(在程序启动时就创建实例)2. 懒汉式单例(在第一次使用时才创建实例) 单例模式的注意事项应用场景 C代码懒汉模式-经典…...
Flutter动画学习二
如何在 Flutter 中使用自定义动画和剪裁(clipping)实现一个简单的动画效果。 前置知识点学习 AnimationController AnimationController 是 Flutter 动画框架中的一个核心类,用于控制动画的生命周期和状态。它提供了一种灵活的方式来定义动…...
讯飞语音听写WebApi(流式)【React Native版】
假设已有 Base64 编码的音频文件(16kHz, s16le, pcm) 1、获取websocket url import * as CryptoJS from crypto-js;/*** 获取websocket url*/ const getWebSocketUrl () > {const config {// 请求地址hostUrl: "wss://iat-api.xfyun.cn/v2/iat",host: "i…...
【Linux编程】一个基于 C++ 的 TCP 客户端异步(epoll)框架(一))
TcpClient 类的设计与实现:一个基于 C 的 TCP 客户端框架 在现代网络编程中,TCP(传输控制协议)客户端是实现网络通信的基础组件之一。本文将详细介绍一个基于 C 的 TcpClient 类的设计与实现,该类提供了创建 TCP 连接…...
PG备份恢复--pg_dump
pg_dump pg_dump 是一个逻辑备份工具。使用 pg_dump 可以在数据库处于使用状态下进行一致 性的备份,它不会阻塞其他用户对数据库的访问 。 一致性备份是 pg_dump 开始运行时,给数据库打了一个快照,且在 pg_dump 运行过程 中发生的更新将不会被备份。 …...
pikachu靶场搭建详细步骤
一、靶场下载 点我去下载 二、靶场安装 需要的环境: mysqlApaches(直接使用小皮面板Phpstudy:https://www.xp.cn/),启动他们 设置网站,把靶场的路径对应过来 对应数据库的信息 由于没有核对数据库的信…...
HarmonyOS NEXT开发进阶(五):装饰器讲解
一、Provide Consume 父组件与子组件的子组件(官方叫法:后代组件)双向同步数据(即,父组件与后代组件可以相互操作 Provide 修饰的数据) 注意:Provide 与 Consume声明的变量名必须一致。 import {TestChild } from .…...
【编译原理】往年题汇总(山东大学软件学院用)
🌈 个人主页:十二月的猫-CSDN博客 🔥 系列专栏: 🏀编译原理_十二月的猫的博客-CSDN博客 💪🏻 十二月的寒冬阻挡不了春天的脚步,十二点的黑夜遮蔽不住黎明的曙光 目录 1. 前言 2. …...
【漏洞复现】F5 BIG-IP Next Central Manager SQL注入漏洞(CVE-2024-26026)
免责声明 请勿利用文章内的相关技术从事非法测试,由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,作者不为此承担任何责任。工具来自网络,安全性自测,如有侵权请联系删除。本次测试仅供学习使用,如若非法他用,与平台和本文作…...
设计模式-创建型-单例模式
1. 单例模式简介 单例模式(Singleton Pattern)是一种常见的创建型设计模式,它确保一个类只有一个实例,并提供全局访问点。在很多情况下,我们只希望某个类在整个应用程序中有一个唯一的实例,且该实例需要在…...
VBA技术资料MF243:利用第三方软件复制PDF数据到EXCEL
我给VBA的定义:VBA是个人小型自动化处理的有效工具。利用好了,可以大大提高自己的工作效率,而且可以提高数据的准确度。“VBA语言専攻”提供的教程一共九套,分为初级、中级、高级三大部分,教程是对VBA的系统讲解&#…...
【2024最新】基于Python+Mysql+django的水果销售系统Lw+PPT
作者:计算机搬砖家 开发技术:SpringBoot、php、Python、小程序、SSM、Vue、MySQL、JSP、ElementUI等,“文末源码”。 专栏推荐:SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏:Java精选实战项…...
从开发到安全:SpringBoot/Struts2/Laravel框架那些“第三方组件”挖出的坑,你的项目踩中了吗?
第三方组件安全黑洞:主流开发框架中那些被忽视的高危依赖 当我们在讨论框架安全时,往往聚焦于SpringBoot、Laravel等核心框架本身,却忽略了那些如影随形的第三方组件。这些"搭便车"的依赖项,正成为企业应用安全的阿喀琉…...
OpenClaw安全防护方案:Phi-3-mini-128k-instruct任务执行边界控制
OpenClaw安全防护方案:Phi-3-mini-128k-instruct任务执行边界控制 1. 为什么需要安全防护 当我第一次让OpenClaw接管本地电脑操作权限时,那种既兴奋又忐忑的心情至今记忆犹新。看着AI自动整理文件、发送邮件、执行脚本的同时,一个挥之不去的…...
idea低版本用高版本的jdk
第二步:把 Project 也改成 JDK17 File → Project Structure (CtrlAltShiftS) Project SDK → 选 17 Language level → 选 17 左边点 Modules每一个模块的 Language level 都改成 17二、分步修复(按顺序执行,100% 解决) 修复 Mav…...
Docker容器优化全攻略
Docker容器优化全攻略 引言:Docker的效率革命 哥们,别整那些花里胡哨的!作为一个前端开发兼摇滚鼓手,我最烦的就是容器体积大、启动慢、运行卡。Docker容器的优化直接关系到部署效率、运行性能和资源消耗。今天,我就给…...
Go语言的项目结构:从单体到微服务
Go语言的项目结构:从单体到微服务 项目结构的重要性 在软件开发中,项目结构是影响代码质量和可维护性的关键因素。一个良好的项目结构可以: 提高代码的可读性和可维护性促进团队协作和代码共享便于测试和部署支持代码的重用和扩展降低项目…...
接口实现第二步骤
接口实现流程模块化路由 -> API 接口规范文档定义模型类 -> 数据库表 (数据库设计文档)在 crud 文件夹里面创建文件,封装操作数据库的方法在路由处理函数里面调用 crud 封装好的方法,响应结果定义模型类规范基类,…...
C++ 模板元编程性能优化技巧
C模板元编程性能优化技巧 在现代C开发中,模板元编程(TMP)因其编译期计算能力而备受推崇,能够在运行时实现零开销抽象。不当使用可能导致编译时间膨胀或代码可读性下降。本文将介绍几项关键优化技巧,帮助开发者高效利用…...
Driver Store Explorer终极指南:三步清理Windows冗余驱动,快速释放数十GB空间
Driver Store Explorer终极指南:三步清理Windows冗余驱动,快速释放数十GB空间 【免费下载链接】DriverStoreExplorer Driver Store Explorer 项目地址: https://gitcode.com/gh_mirrors/dr/DriverStoreExplorer 你是否发现Windows系统盘空间越来越…...
基于yolov26的桃子成熟度检测系统python源码+pytorch模型+评估指标曲线+精美GUI界面
基于 PyQt5 和 YOLO26 的目标检测桌面应用程序,支持图片、视频和摄像头实时检测。 功能特性 图片检测:支持图片检测视频检测:支持视频文件实时检测与播放摄像头检测:支持实时摄像头视频流检测模型切换:支持加载不同的 …...
4.2 学习笔记
Mysql 数据库专题1.本专题的学习重点1、熟悉Mysql数据库的连接工具2、掌握查询的SQL语句的编写2.什么是数据库数据库就是存储数据的仓库3.为什么要学数据库Mysql在测试过程中,有时候需要通过访问数据库验证数据的正确性比如:验证统计报表....4.企业主流的…...
