当前位置: 首页 > news >正文

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 的垃圾回收器会定期扫描对象图,识别那些存在循环引用但不再被使用的对象,并释放它们的内存。

  • 垃圾回收触发条件:
    1. 手动调用:可以通过 gc 模块的 gc.collect() 方法手动触发。
    2. 自动触发:垃圾回收器会在一定条件下自动运行,比如内存分配达到阈值时。

示例:使用垃圾回收模块

import gc# 查看当前垃圾回收器的状态
print(gc.isenabled())  # 输出: True(自动垃圾回收默认开启)# 禁用垃圾回收
gc.disable()# 手动触发垃圾回收
gc.collect()

3. 内存池机制

Python 对小对象的内存分配进行了优化,通过内存池机制减少了频繁的系统内存分配和释放的开销。

(1)小对象 vs 大对象

  • 小对象(<256字节):
    • Python 使用了专门的内存池(如 PyObject 池)管理小对象。
    • 这些小对象会被分配到固定大小的内存块中,释放后会被重复利用。
  • 大对象(>=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. **内存管理的基本原理**&#xff08;1&#xff09;动态内存分配&#xff08;2&#xff09;引用计数机制 2. **垃圾回收&#xff08;Garbage Collection, GC&#xff09;机制**&#xff08;1&#xff09;循环引用问题&#xff08;2&#xff09;垃圾回收器的作用 3. …...

VSCode调试

目录 C/C远程本地调试插件配置参考 C/C远程本地调试 测试源码&#xff1a;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) 是一种基于人类偏好的强化学习优化方法&#xff0c;用于训练语言模型&#xff0c;使其更好地满足用户需求或偏好。本文将详细介绍 DPO 的核心思想、优化流程&#xff0c;并结合代码…...

fisco-bcos手动搭建webase启动注意事项

手动搭建webase-front启动注意事项 Java环境变量&#xff1a;1.8.301时候的错误 一直提示节点连接不上&#xff0c;无法连接chanale端口 这是官方提供的解决办法Help wanted: solution for secp256k1 being disabled Issue #470 FISCO-BCOS/java-sdk Java SDK 2.x连接节点失败…...

ospf 的 状态机详解

OSPF&#xff08;开放最短路径优先&#xff0c;Open Shortest Path First&#xff09;协议的状态机是其核心部分之一&#xff0c;用于确保路由器之间的邻接关系&#xff08;neighbor relationship&#xff09;建立和路由信息的交换。OSPF的状态机模型由多个状态组成&#xff0c…...

TP5 动态渲染多个Layui表格并批量打印所有表格

记录&#xff1a; TP5 动态渲染多个Layui表格每个表格设置有2行表头&#xff0c;并且第一行表头在页面完成后动态渲染显示内容每个表格下面显示统计信息可点击字段排序一次打印页面上的所有表格打印页面上多个table时,让每个table单独一页 后端代码示例&#xff1a; /*** Nod…...

spring专题笔记(六):bean的自动装配(自动化注入)-根据名字进行自动装配、根据类型进行自动装配。代码演示,通俗易懂。

目录 一、根据名字进行自动装配--byName 二、根据类型进行自动装配 byType 本文章主要是介绍spring的自动装配机制&#xff0c; 用代码演示spring如何根据名字进行自动装配、如何根据类型进行自动装配。代码演示&#xff0c;通俗易懂。 一、根据名字进行自动装配--byName Us…...

监听器listener

文章目录 监听器( listener)对Application内置对象监听的语法和配置对session内置对象监听的语法和配置 监听器( listener) 对象与对象的关系&#xff1a; 继承关联 tomcat一启动创建的顺序&#xff1a;监听器&#xff0c;config&#xff0c;application(全局初始化参数)&am…...

重温设计模式--10、单例模式

文章目录 单例模式&#xff08;Singleton Pattern&#xff09;概述单例模式的实现方式及代码示例1. 饿汉式单例&#xff08;在程序启动时就创建实例&#xff09;2. 懒汉式单例&#xff08;在第一次使用时才创建实例&#xff09; 单例模式的注意事项应用场景 C代码懒汉模式-经典…...

Flutter动画学习二

如何在 Flutter 中使用自定义动画和剪裁&#xff08;clipping&#xff09;实现一个简单的动画效果。 前置知识点学习 AnimationController AnimationController 是 Flutter 动画框架中的一个核心类&#xff0c;用于控制动画的生命周期和状态。它提供了一种灵活的方式来定义动…...

讯飞语音听写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 类的设计与实现&#xff1a;一个基于 C 的 TCP 客户端框架 在现代网络编程中&#xff0c;TCP&#xff08;传输控制协议&#xff09;客户端是实现网络通信的基础组件之一。本文将详细介绍一个基于 C 的 TcpClient 类的设计与实现&#xff0c;该类提供了创建 TCP 连接…...

PG备份恢复--pg_dump

pg_dump pg_dump 是一个逻辑备份工具。使用 pg_dump 可以在数据库处于使用状态下进行一致 性的备份,它不会阻塞其他用户对数据库的访问 。 一致性备份是 pg_dump 开始运行时&#xff0c;给数据库打了一个快照&#xff0c;且在 pg_dump 运行过程 中发生的更新将不会被备份。 …...

pikachu靶场搭建详细步骤

一、靶场下载 点我去下载 二、靶场安装 需要的环境&#xff1a; mysqlApaches&#xff08;直接使用小皮面板Phpstudy&#xff1a;https://www.xp.cn/&#xff09;&#xff0c;启动他们 设置网站&#xff0c;把靶场的路径对应过来 对应数据库的信息 由于没有核对数据库的信…...

HarmonyOS NEXT开发进阶(五):装饰器讲解

一、Provide Consume 父组件与子组件的子组件(官方叫法&#xff1a;后代组件)双向同步数据&#xff08;即&#xff0c;父组件与后代组件可以相互操作 Provide 修饰的数据&#xff09; 注意&#xff1a;Provide 与 Consume声明的变量名必须一致。 import {TestChild } from .…...

【编译原理】往年题汇总(山东大学软件学院用)

&#x1f308; 个人主页&#xff1a;十二月的猫-CSDN博客 &#x1f525; 系列专栏&#xff1a; &#x1f3c0;编译原理_十二月的猫的博客-CSDN博客 &#x1f4aa;&#x1f3fb; 十二月的寒冬阻挡不了春天的脚步&#xff0c;十二点的黑夜遮蔽不住黎明的曙光 目录 1. 前言 2. …...

【漏洞复现】F5 BIG-IP Next Central Manager SQL注入漏洞(CVE-2024-26026)

免责声明 请勿利用文章内的相关技术从事非法测试,由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,作者不为此承担任何责任。工具来自网络,安全性自测,如有侵权请联系删除。本次测试仅供学习使用,如若非法他用,与平台和本文作…...

设计模式-创建型-单例模式

1. 单例模式简介 单例模式&#xff08;Singleton Pattern&#xff09;是一种常见的创建型设计模式&#xff0c;它确保一个类只有一个实例&#xff0c;并提供全局访问点。在很多情况下&#xff0c;我们只希望某个类在整个应用程序中有一个唯一的实例&#xff0c;且该实例需要在…...

VBA技术资料MF243:利用第三方软件复制PDF数据到EXCEL

我给VBA的定义&#xff1a;VBA是个人小型自动化处理的有效工具。利用好了&#xff0c;可以大大提高自己的工作效率&#xff0c;而且可以提高数据的准确度。“VBA语言専攻”提供的教程一共九套&#xff0c;分为初级、中级、高级三大部分&#xff0c;教程是对VBA的系统讲解&#…...

【2024最新】基于Python+Mysql+django的水果销售系统Lw+PPT

作者&#xff1a;计算机搬砖家 开发技术&#xff1a;SpringBoot、php、Python、小程序、SSM、Vue、MySQL、JSP、ElementUI等&#xff0c;“文末源码”。 专栏推荐&#xff1a;SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏&#xff1a;Java精选实战项…...

SkyWalking 10.2.0 SWCK 配置过程

SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外&#xff0c;K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案&#xff0c;全安装在K8S群集中。 具体可参…...

ElasticSearch搜索引擎之倒排索引及其底层算法

文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...

Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)

目录 一、&#x1f44b;&#x1f3fb;前言 二、&#x1f608;sinx波动的基本原理 三、&#x1f608;波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、&#x1f30a;波动优化…...

鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南

1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发&#xff0c;使用DevEco Studio作为开发工具&#xff0c;采用Java语言实现&#xff0c;包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...

C#学习第29天:表达式树(Expression Trees)

目录 什么是表达式树&#xff1f; 核心概念 1.表达式树的构建 2. 表达式树与Lambda表达式 3.解析和访问表达式树 4.动态条件查询 表达式树的优势 1.动态构建查询 2.LINQ 提供程序支持&#xff1a; 3.性能优化 4.元数据处理 5.代码转换和重写 适用场景 代码复杂性…...

从“安全密码”到测试体系:Gitee Test 赋能关键领域软件质量保障

关键领域软件测试的"安全密码"&#xff1a;Gitee Test如何破解行业痛点 在数字化浪潮席卷全球的今天&#xff0c;软件系统已成为国家关键领域的"神经中枢"。从国防军工到能源电力&#xff0c;从金融交易到交通管控&#xff0c;这些关乎国计民生的关键领域…...

elementUI点击浏览table所选行数据查看文档

项目场景&#xff1a; table按照要求特定的数据变成按钮可以点击 解决方案&#xff1a; <el-table-columnprop"mlname"label"名称"align"center"width"180"><template slot-scope"scope"><el-buttonv-if&qu…...

MFE(微前端) Module Federation:Webpack.config.js文件中每个属性的含义解释

以Module Federation 插件详为例&#xff0c;Webpack.config.js它可能的配置和含义如下&#xff1a; 前言 Module Federation 的Webpack.config.js核心配置包括&#xff1a; name filename&#xff08;定义应用标识&#xff09; remotes&#xff08;引用远程模块&#xff0…...

消防一体化安全管控平台:构建消防“一张图”和APP统一管理

在城市的某个角落&#xff0c;一场突如其来的火灾打破了平静。熊熊烈火迅速蔓延&#xff0c;滚滚浓烟弥漫开来&#xff0c;周围群众的生命财产安全受到严重威胁。就在这千钧一发之际&#xff0c;消防救援队伍迅速行动&#xff0c;而豪越科技消防一体化安全管控平台构建的消防“…...

《信号与系统》第 6 章 信号与系统的时域和频域特性

目录 6.0 引言 6.1 傅里叶变换的模和相位表示 6.2 线性时不变系统频率响应的模和相位表示 6.2.1 线性与非线性相位 6.2.2 群时延 6.2.3 对数模和相位图 6.3 理想频率选择性滤波器的时域特性 6.4 非理想滤波器的时域和频域特性讨论 6.5 一阶与二阶连续时间系统 6.5.1 …...