python的内存管理机制

目录

  • 内存分配方式
    • 自动内存管理
    • 内存分配策略
  • 垃圾回收机制
    • 引用计数垃圾回收
      • 对象创建和引用关系
      • 引用计数的状态
      • 删除变量
    • 标记 - 清除垃圾回收
  • 内存分配的区域划分
    • 栈内存
    • 堆内存
  • 内存管理的优化
    • 内存池技术
    • 对象共享

Python 的内存管理机制是其运行效率和安全性的重要保障,主要包括以下几个方面:

内存分配方式

自动内存管理

  • Python 采用自动内存管理,主要通过垃圾回收机制来实现。它不需要程序员手动释放内存【典型的例子C和C++,使用malloc和free等函数】,大大减少了内存泄漏等错误的发生。例如,在 Python 中创建一个列表对象:
    my_list = [1, 2, 3]
    
    当这个列表不再被任何变量引用时,Python 的垃圾回收机制会自动回收它所占用的内存。
  • 这种自动管理方式使得程序员可以更专注于程序逻辑的实现,而不是内存管理的细节。

内存分配策略

  • Python 使用引用计数作为主要的内存分配策略。每个对象都有一个引用计数器,当一个对象被创建时,它的引用计数器被设置为 1。例如:
    a = 10
    
    此时,整数对象 10 的引用计数为 1。
  • 当一个对象被赋值给另一个变量时,引用计数会增加。例如:
    b = a
    
    整数对象 10 的引用计数变为 2。
  • 当一个对象被删除或者其引用被重新赋值给其他对象时,引用计数会减少。例如:
    del a
    
    整数对象 10 的引用计数变为 1。当引用计数变为 0 时,Python 的垃圾回收机制就会回收该对象所占用的内存。

垃圾回收机制

引用计数垃圾回收

  • 这是 Python 最主要的垃圾回收方式。如前面所述,通过引用计数来判断对象是否还有用。这种方式的优点是简单高效,能够及时回收不再使用的对象。例如,一个复杂的嵌套数据结构,当它的顶层变量被删除后,其内部所有对象的引用计数都会逐渐减少,一旦变为 0 就会被回收。
  • 但是引用计数也有缺点,它无法处理循环引用的情况。例如:
    a = []
    b = []
    a.append(b)
    b.append(a)
    
  • 循环引用是指两个或多个对象之间互相引用,形成一个闭环。这种情况下,即使这些对象没有被外部变量引用【a 中的元素(即 b)和 b 中的元素(即 a)是内部的引用关系,这些引用关系是对象内部的结构,而不是外部变量的直接引用】,它们的引用计数也不会为0,因为它们互相引用。

对象创建和引用关系

  • a = [] 创建了一个空列表对象 a,此时 a 的引用计数为 1(a 本身引用了它)。
  • b = [] 创建了另一个空列表对象 b,此时 b 的引用计数也为 1(b 本身引用了它)。
  • a.append(b) 将对象 b 添加到列表 a 中,此时 b 的引用计数增加 1,变为 2(b 本身和 a 中的元素引用了它)。
  • b.append(a) 将对象 a 添加到列表 b 中,此时 a 的引用计数也增加 1,变为 2(a 本身和 b 中的元素引用了它)。

引用计数的状态

现在,ab 的引用计数都是 2:

  • aa 本身和 b 中的元素引用。
  • bb 本身和 a 中的元素引用。

删除变量

假设我们执行以下操作:

del a
del b
  • 删除变量 a 后,a 的引用计数减少 1,变为 1(只剩下 b 中的元素引用它)。
  • 删除变量 b 后,b 的引用计数也减少 1,变为 1(只剩下 a 中的元素引用它)。

此时,ab 的引用计数仍然为 1,因为它们互相引用。即使我们删除了外部变量 ab,它们的引用计数也不会变为 0,因此引用计数机制无法回收它们。

标记 - 清除垃圾回收

  • 为了处理循环引用的问题,Python 还采用了标记 - 清除垃圾回收机制。该机制会定期运行,它从根对象集合(如全局变量、栈中的变量等)开始,标记所有可达的对象。然后扫描整个内存堆,将未标记的对象视为垃圾进行回收。
  • 例如,在上述循环引用的例子中,当标记 - 清除机制运行时,它会发现 a 和 b 之间虽然互相引用,但它们没有被根对象【在 Python 的垃圾回收机制中,根对象是指那些始终被程序直接引用的对象;例如:全局变量、局部变量、活动对象、内置对象等】集合引用,所以会被标记为垃圾并回收。

内存分配的区域划分

栈内存

  • 主要用于存储局部变量、函数调用的上下文等。在 Python 中,当一个函数被调用时,会为其创建一个栈帧,栈帧中包含了函数的局部变量等信息。例如:
    def my_function():x = 10y = 20return x + y
    
    当调用 my_function() 时,会创建一个栈帧,其中存储了变量 x 和 y。栈内存的分配和释放速度很快,当函数调用结束时,栈帧会被销毁,其中的变量占用的内存也会被释放。

堆内存

  • 主要用于存储对象实例等。例如,创建一个类的实例:
    class MyClass:def __init__(self, value):self.value = value
    obj = MyClass(100)
    
    这里的 obj 是一个对象实例,它存储在堆内存中。堆内存的分配和释放相对复杂,需要通过垃圾回收机制来管理。

内存管理的优化

内存池技术

  • Python 的内存管理使用了内存池技术。内存池是一种预先分配一块较大的内存空间,然后从这个空间中分配小块内存给对象的技术。例如,对于小整数(通常在 -5 到 256 之间),Python 会预先分配好这些整数对象存储在内存池中,当程序需要使用这些小整数时,直接从内存池中获取,避免了频繁的内存分配和释放操作,提高了内存分配的效率。

对象共享

  • Python 会尽量共享一些不可变对象。例如,字符串对象在某些情况下会共享。如果程序中有多个地方使用相同的字符串,Python 会尽量让它们指向同一个字符串对象,而不是创建多个相同的字符串对象,这样可以节省内存空间。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/76386.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

火山引擎coze用户市场

火山引擎 **Coze**(扣子)的用户市场主要集中在 **需要快速构建和部署智能对话应用的企业及开发者群体**,覆盖多个行业与场景。以下是具体分析: --- ### **一、核心用户群体** 1. **企业用户** - **互联网/科技公司**&#…

Java 责任链模式 详解

责任链模式详解 一、责任链模式概述 责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,它允许你将请求沿着处理链传递,直到有一个处理者能够处理它为止。这种模式解耦了请求的发送者和接收者,使多个对象都有机会处理请求。…

【C++初阶】--- string类

1.STL简介 STL(standard template libaray-标准模板库):是C标准库的重要组成部分,不仅是一个可复用的组件库,而且是一个包罗数据结构与算法的软件框架。 2.string类 2.1什么是string类 std::string 类是 C 标准库中用于处理和操作字符串…

Ubuntu 20.04 中 Git 的安装、配置和基本操作指南

本文为经验 所谈 使用版本为ubuntu20.04 1 ubuntu的git初始化 1.安装git sudo apt-get install git 可通过git --version 命令查看,正常输出git版本号即安装成功。 2.配置用户名和邮箱名 git config --global user.name "Your Name" git config --globa…

conda 激活环境vscode的Bash窗口

多份conda环境注意事项,当时安装了两个conda环境,miniconda和conda,导致环境总是冲突矛盾。初始化时需要更加注意。 $ C:/Users/a_hal/miniconda3/Scripts/conda.exe init bash能够显示用哪里的conda环境命令执行。 然后直接conda activate…

Mac下小智AI本地环境部署

可以进行聊天、编写程序、播放歌曲等等的小智语音聊天小助手,在Mac环境下修改源代码,值得拥有。本篇内容主要讲解Mac下环境的搭建,WebSocket的修改。注:环境python3.12.0、ESP-IDF5.4.0、开发板ESP32S3。 目录 1.Git安装2.Python…

Linux安装Cmake (Centos 7.9)

cmake安装 这个虽然已经更新到了4.0.0版本了,但是我们要用3.5版本的,因为这个比较稳定 官方地址:https://github.com/Kitware/CMake/releases/tag/v3.5.0,选择那个cmake-3.5.0-Linux-x86_64.tar.gz下载, 首先解压文…

基于 SpringBoot 的旧物置换网站

收藏关注不迷路!! 🌟文末获取源码数据库🌟 感兴趣的可以先收藏起来,还有大家在毕设选题(免费咨询指导选题),项目以及论文编写等相关问题都可以给我留言咨询,希望帮助更多…

ELK 通过 logstash 收集单个/多个日志文件

一、收集单个日志文件 注意事项: logstah 服务默认启动用户和组是 logstash被收集的日志文件有读的权限并对写入的文件有写权限而 logstash 是普通用户 1.1 编辑 logstash 配置文件 vim /etc/logstash/conf.d/test.conf input {file {path > "/var/log/…

分享一个Drools规则引擎微服务Docker部署

通常我们都是把Drools作为嵌入式使用,但在微服务泛滥时代,还在老套的嵌入式显然不符合微服务架构要求,本文分享一个把Drools作为微服务独立部署的方案。 本方案基于Drools引擎微服务,提供REST接口。 1、可以动态部署Drools规则2…

Mac 本地化部署 dify

Macbook 本地化部署 dify 目录 Macbook 本地化部署 dify安装dockerdocker下载地址 安装dify下载dify到本地github可能遇到的问题: github打开超时在本地解压dify.zip文件本地化部署docker部署可能遇到的问题: 部署超时登录体验 dify 安装docker docker下载地址 根据电脑芯片选…

串口中断接收与环形缓冲实例(apollo3 blue plus)

#define DEV_UART1 1 #define GPS_POWER_PIN 13 #define GPS_LOG_ENABLE 1 #define MAX_UART1_SIZE 1024 #define AM_BSP_GPIO_COM_UART1_TX 8 #define AM_BSP_GPIO_COM_UART1_RX 9 // 定义环形缓冲区结构 typed…

操作系统高频(五)linux命令

操作系统高频(五)linux命令 1.Linux中查看进程运行状态的指令、tar解压文件的参数。⭐⭐⭐ 在Linux中,可以使用以下指令查看进程的运行状态: top: 用于实时监视系统的进程活动和系统资源使用情况。在终端中运行top…

Spring Boot 快速入手

前言:为什么选择 Spring Boot? 🚀 在现代 Java 开发中,Spring Boot 已成为最流行的后端框架之一。无论是小型 Web 应用、企业级系统,还是微服务架构,Spring Boot 都能提供快速开发、自动配置、轻量级部署的…

oracle-blob导出,在ob导入失败

导出&#xff1a; [oraclelncs dmp]$ /home/oracle/sqluldr2 gistar/res#pwd192.168.205.58:1521/lndb query"select * from an_odn_picture where length(PIC_CONTENT)<25000" filean_odn_picture.csv Charsetutf8 textCSV 0 rows exported at 2025-…

RK3568 pinctrl内容讲解

文章目录 一、pinctrl的概念`pinctrl` 的作用设备树中的 `pinctrl` 节点典型的 `pinctrl` 节点结构例子`pinctrl` 的重要性总结二、RK3568的pinctrl讲解1. `pinctrl` 节点2. `gpio0` 至 `gpio4` 子节点每个 `gpioX` 子节点的结构和作用3. `gpio1` 到 `gpio4` 子节点总结1. `aco…

北京南文观点:后糖酒会营销,以战略传播重构品牌信心坐标

第112届全国糖酒会落下帷幕&#xff0c;参展品牌面临一个关键命题。如何在流量洪流中沉淀品牌价值&#xff1f;北京南文&#xff08;全称&#xff1a;南文乐园科技文化&#xff08;北京&#xff09;有限公司&#xff09;认为&#xff0c;糖酒会的结束恰是算法时代品牌认知战的真…

html5时钟升级!支持切换深浅模式 Canvas实现现代化动态时钟

HTML5 Canvas实现现代化动态时钟 这里写目录标题 HTML5 Canvas实现现代化动态时钟项目介绍技术实现1. 项目架构2. Canvas绘图实现2.1 表盘绘制2.2 刻度绘制2.3 指针绘制 3. 动画效果4. 主题切换 项目亮点技术要点总结项目收获改进方向结语 项目介绍 本项目使用HTML5 Canvas技术…

《SRv6 网络编程:开启IP网络新时代》第2章、第3章:SRv6基本原理和基础协议

背景 根据工作要求、本人掌握的知识情况&#xff0c;仅针对《SRv6 网络编程&#xff1a;开启IP网络新时代》书籍中涉及的部分知识点进行总结梳理&#xff0c;并与工作小组进行分享&#xff0c;不涉及对原作的逐字搬运。 问题 组内同事提出的问题&#xff1a;本文缺扩展头描述…

卫星电话究竟是“锦上添花”?还是“刚需之选”?

在万物互联的时代浪潮中&#xff0c;卫星电话究竟是可有可无的“锦上添花”&#xff0c;还是至关重要的“刚需之选”&#xff1f;随着通信技术的持续进步与应用场景的日益拓展&#xff0c;这一问题的答案正逐渐明晰。 在5G基站覆盖99%行政村的今天&#xff0c;人类依然要直面自…