当前位置: 首页 > 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精选实战项…...

测试微信模版消息推送

进入“开发接口管理”--“公众平台测试账号”&#xff0c;无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息&#xff1a; 关注测试号&#xff1a;扫二维码关注测试号。 发送模版消息&#xff1a; import requests da…...

Flask RESTful 示例

目录 1. 环境准备2. 安装依赖3. 修改main.py4. 运行应用5. API使用示例获取所有任务获取单个任务创建新任务更新任务删除任务 中文乱码问题&#xff1a; 下面创建一个简单的Flask RESTful API示例。首先&#xff0c;我们需要创建环境&#xff0c;安装必要的依赖&#xff0c;然后…...

椭圆曲线密码学(ECC)

一、ECC算法概述 椭圆曲线密码学&#xff08;Elliptic Curve Cryptography&#xff09;是基于椭圆曲线数学理论的公钥密码系统&#xff0c;由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA&#xff0c;ECC在相同安全强度下密钥更短&#xff08;256位ECC ≈ 3072位RSA…...

【MATLAB代码】基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),附源代码|订阅专栏后可直接查看

文章所述的代码实现了基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),针对传感器观测数据中存在的脉冲型异常噪声问题,通过非线性加权机制提升滤波器的抗干扰能力。代码通过对比传统KF与MCC-KF在含异常值场景下的表现,验证了后者在状态估计鲁棒性方面的显著优…...

基于PHP的连锁酒店管理系统

有需要请加文章底部Q哦 可远程调试 基于PHP的连锁酒店管理系统 一 介绍 连锁酒店管理系统基于原生PHP开发&#xff0c;数据库mysql&#xff0c;前端bootstrap。系统角色分为用户和管理员。 技术栈 phpmysqlbootstrapphpstudyvscode 二 功能 用户 1 注册/登录/注销 2 个人中…...

在 Spring Boot 中使用 JSP

jsp&#xff1f; 好多年没用了。重新整一下 还费了点时间&#xff0c;记录一下。 项目结构&#xff1a; pom: <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://ww…...

永磁同步电机无速度算法--基于卡尔曼滤波器的滑模观测器

一、原理介绍 传统滑模观测器采用如下结构&#xff1a; 传统SMO中LPF会带来相位延迟和幅值衰减&#xff0c;并且需要额外的相位补偿。 采用扩展卡尔曼滤波器代替常用低通滤波器(LPF)&#xff0c;可以去除高次谐波&#xff0c;并且不用相位补偿就可以获得一个误差较小的转子位…...

【无标题】湖北理元理律师事务所:债务优化中的生活保障与法律平衡之道

文/法律实务观察组 在债务重组领域&#xff0c;专业机构的核心价值不仅在于减轻债务数字&#xff0c;更在于帮助债务人在履行义务的同时维持基本生活尊严。湖北理元理律师事务所的服务实践表明&#xff0c;合法债务优化需同步实现三重平衡&#xff1a; 法律刚性&#xff08;债…...

rknn toolkit2搭建和推理

安装Miniconda Miniconda - Anaconda Miniconda 选择一个 新的 版本 &#xff0c;不用和RKNN的python版本保持一致 使用 ./xxx.sh进行安装 下面配置一下载源 # 清华大学源&#xff08;最常用&#xff09; conda config --add channels https://mirrors.tuna.tsinghua.edu.cn…...

jdbc查询mysql数据库时,出现id顺序错误的情况

我在repository中的查询语句如下所示&#xff0c;即传入一个List<intager>的数据&#xff0c;返回这些id的问题列表。但是由于数据库查询时ID列表的顺序与预期不一致&#xff0c;会导致返回的id是从小到大排列的&#xff0c;但我不希望这样。 Query("SELECT NEW com…...