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

比较Python和Rust的内存管理机制

大家好,内存管理是编程语言的基础,它确保着资源被有效利用,不同的编程语言采用不同的策略来管理内存。有些语言需要程序员手动管理内存,有些语言则自动化了内存管理过程。Python和Rust都采用了垃圾收集(Garbage Collection)机制来管理内存,但它们各自的实现方式有很大的不同。

1.Python:引用计数与分代式垃圾收集

Python使用称为“引用计数”的技术进行垃圾收集,每个对象都有一个计数器,跟踪对其的引用数量。当此计数达到零时,对象就会从内存中删除。

换句话说,每个内存中的对象都有一个关联的数字(称为“引用计数”),跟踪它被多少变量或其他对象指向。

import sys# 创建对象x
x = [1, 2, 3]# 获取x的引用计数(应该是1)
print("Reference Count of x:", sys.getrefcount(x) - 1)# 创建x的引用
y = x# 引用计数增加 1
print("Reference Count of x after y = x:", sys.getrefcount(x) - 1)# 删除引用
del y# 引用计数减少 1
print("Reference Count of x after del y:", sys.getrefcount(x) - 1)
Reference Count of x: 1
Reference Count of x after y = x: 2
Reference Count of x after del y: 1

Python采用称为“分代垃圾收集”的生成式方法,来进一步提高垃圾收集的效率。对象分为三个不同的“代”:

  • Generation 0:新对象

对象最初分配在第0代,这是其生命周期的第一阶段。

# 导入 gc(垃圾回收)模块
import gc# 启用调试以打印垃圾收集信息
gc.set_debug(gc.DEBUG_STATS)# 创建一个新的列表对象;该对象最初处于第 0 代
new_object = [1, 2, 3]# 仅在第 0 代手动运行垃圾回收
gc.collect(0)

创建new_object时,它是一个新对象,会在第0代开始其生命

  • Generation 1:经历过一次垃圾回收周期的对象

在第0代垃圾回收周期中未被回收的对象会转移到第1代。

# 创建一个持久对象
persistent_object = {"key": "value"}# 在第 0 代运行垃圾回收
gc.collect(0)# 此时,"persistent_object "存活并进入第 1 代

在Python的分代式垃圾收集中,当一个对象首次建时,它会被放入第0代。每当对该代进行垃圾收集循环时,Python会寻找不再需要的对象(即引用计数为零的对象),以删除它们并释放内存。

如果像persistent\_object一样的对象在这个垃圾收集周期中存活下来,这意味着它仍在被引用或使用,它就会 "老化 "并进入下一代,在这种情况下是第1代。

这背后的原理是,新创建的对象更有可能是短命的,会很快被垃圾回收。另一方面,如果一个对象已经经历过一次垃圾回收周期,那么它就更有可能是长寿的,因此它会被转移到较老的一代,接受较少频率的检查。

由于persistent_object仍在使用中(在代码中的某个地方被引用),它的引用计数并不为零,因此它能在第0代垃圾回收过程中存活下来。

  • Generation 2:存活超过一个垃圾回收周期的对象

经过多次垃圾收集周期的对象最终会转到第2代。

# 创建另一个持久对象
very_persistent_object = (1, 2, 3)# 对第 0 代和第 1 代进行垃圾回收
gc.collect(0)
gc.collect(1)# 此时,"very_persistent_object "存活下来,并应进入第 2 代

在这里,very_persistent_object在第0代和第1代的垃圾回收中都能存活,因此它将转移到第2代。

实际上,开发者通常不需要手动控制或监控这些生成,Python 的垃圾回收器会自动处理,但了解它们的工作原理对调试和优化很有帮助。

2.Rust:基于所有权和借用的内存管理

Rust的内存管理方式与具有垃圾收集的语言(如Python)有着本质区别,它依赖于“所有权”和“借用”的概念来确保资源的安全管理。

2.1 所有权

在Rust中,每个值都有一个“所有者”,该值在其所有者存在时有效。当所有者超出范围时,该值及其资源会被自动释放,这样就不需要单独的垃圾回收过程了。

以下是个示例:

fn main() {let s1 = String::from("hello");  // s1是值"hello"的所有者let s2 = s1;  // s1的所有权被传递给s2// println!("{}", s1);  // 这将导致错误,因为s1不再拥有该值println!("{}", s2);  // 这是可以的,s2现在是所有者
}  // s2超出范围,“hello”被释放

在本例中,s1最初拥有字符串 "hello",然后所有权转移到s2。当s2main()的结尾超出范围时,字符串"hello"会被自动释放。

2.2 借用

有时,需要访问一个值而不需要取得其所有权,因此 Rust 允许 "借用",可以借用一个可变或不可变的引用值。

不可变借用:

fn main() {let s1 = String::from("hello");let len = calculate_length(&s1);  // &s1借用s1而不拥有它println!("'{}'的长度为{}.", s1, len);
}fn calculate_length(s: &String) -> usize {s.len()
}

可变借用:

fn main() {let mut s1 = String::from("hello");change_string(&mut s1);  // &mut s1以可变引用形式借用s1println!("{}", s1);
}fn change_string(s: &mut String) {s.push_str(", world");
}

在这些示例中,&s1&mut s1借用了值,但没有取得所有权,从而允许 s1在函数调用后继续使用。

Rust 方法的主要优势在于,它可以精确控制代码的哪些部分可以使用、修改或取消分配值,从而使程序更安全、更高效,而无需进行垃圾收集。

相关文章:

比较Python和Rust的内存管理机制

大家好,内存管理是编程语言的基础,它确保着资源被有效利用,不同的编程语言采用不同的策略来管理内存。有些语言需要程序员手动管理内存,有些语言则自动化了内存管理过程。Python和Rust都采用了垃圾收集(Garbage Collec…...

Linux系统——Shell脚本——一键安装LNMP

#!/bin/bash #安装nginx echo "安装nginx服务" wget http://nginx.org/download/nginx-1.11.4.tar.gz &>/dev/null if [ $? -eq 0 ] thenecho "nginx-1.11.4安装包下载完成"echo "--开始安装必要的依赖文件--"yum install -y gcc gcc-c…...

算法复习之二分【备战蓝桥杯】

二分模板一共有两个,分别适用于不同情况。 算法思路:假设目标值在闭区间[l, r]中, 每次将区间长度缩小一半,当l r时,我们就找到了目标值。 版本一 当我们将区间[l, r]划分成[l, mid]和[mid 1, r]时,其更…...

如何做代币分析:以 SHIB 币为例

作者:lesleyfootprint.network 编译:cicifootprint.network 数据源:SHIB Token Dashboard (仅包括以太坊数据) 在加密货币和数字资产领域,代币分析起着至关重要的作用。代币分析指的是深入研究与代币相关…...

Springboot+vue的考勤管理系统(有报告)。Javaee项目,springboot vue前后端分离项目。

演示视频: Springbootvue的考勤管理系统(有报告)。Javaee项目,springboot vue前后端分离项目。 项目介绍: 采用M(model)V(view)C(controller)三层…...

https://htmlunit.sourceforge.io/

https://htmlunit.sourceforge.io/ 爬虫 HtmlUnit – Welcome to HtmlUnit HtmlUnit 3.11.0 API https://mvnrepository.com/artifact/net.sourceforge.htmlunit/htmlunit/2.70.0 https://s01.oss.sonatype.org/service/local/repositories/releases/content/org/htmlunit…...

回文链表(leetcode)

我自己第一个写的代码: bool isPalindrome(struct ListNode* head){struct ListNode* tail NULL;struct ListNode* pos NULL;if( head->next NULL){return true;}while( 1 ){if( head->next NULL || (head->next->next NULL && head->…...

大语言模型(LLM)技术名词表(一)

LLMs on a Phone:指在手机设备上运行的大型语言模型。 Scalable Personal AI:指用户可以在个人设备上对AI模型进行微调的技术。 Responsible Release:发布AI模型时考虑社会、法律和伦理影响的做法。 Multimodality:AI模型能处理…...

C++ 快速排序快速选择

目录 1、75. 颜色分类 2、912. 排序数组 3、 215. 数组中的第K个最大元素 4、LCR 159. 库存管理 III 1、75. 颜色分类 思路:利用快速排序思路,使用三指针分块进行优化。 [0,left]——小于key[left1,right-1]——等于key[right,nums.size()]——大于k…...

雅马哈伺服器TS-S系列说明具体详情内容可参看PDF目录内容

雅马哈伺服器TS-S系列说明具体详情内容可参看PDF目录内容...

SpringBoot底层原理

SpringBoot底层原理 一 配置优先级 1.配置方式 Springboot中支持三种配置方式,分别为: application.propertiesapplication.ymlapplication.yaml 2.配置优先级 当存在多份配置文件时,配置文件会按照它们的优先级生效。 优先级从高到底…...

【golang】25、图片操作

用 “github.com/fogleman/gg” 可以画线, 框 用 “github.com/disintegration/imaging” 可以变换颜色 一、渲染 1.1 框和字 import "github.com/fogleman/gg"func DrawRectangles(inPath string, cRects []ColorTextRect, fnImgNameChange FnImgNameChange) (st…...

kswapd0挖矿病毒攻击记录

文章目录 一、起因与病毒分析1、起因2、阿里云告警2.1 恶意脚本代码执行12.2 恶意脚本代码执行22.3恶意脚本代码执行32.4 恶意脚本代码执行4 3、病毒简单分析3.1 病毒的初始化3.2 病毒本体执行 4、总结 二、ubuntu自救指南1、病毒清理2、如何防御 一、起因与病毒分析 1、起因 …...

如何使用 takeUntil RxJS 操作符来声明性地管理订阅

简介 Angular 处理取消订阅可观察对象的操作,比如从 HTTP 服务返回的可观察对象或者使用 async 管道时。然而,对于其他情况,管理所有订阅并确保取消长期存在的订阅可能会变得困难。而且,取消大部分订阅的策略也会带来自己的问题。…...

在Centos中用Docker部署oracle-12c

一、介绍 Oracle 12c是Oracle 11g的后续版本。12c代表云计算(Cloud Computing),这是Oracle在该版本中强调的一个关键概念。它具有多租户架构、数据库内存、安全增强、大数据管理和自动化管理等功能。它被广泛应用于企业级应用程序和大型数据…...

JS进阶——高级技巧

版权声明 本文章来源于B站上的某马课程,由本人整理,仅供学习交流使用。如涉及侵权问题,请立即与本人联系,本人将积极配合删除相关内容。感谢理解和支持,本人致力于维护原创作品的权益,共同营造一个尊重知识…...

TG-ADMIN 权限管理系统

项目简介 该项目是一款基于 SpringBoot + Vue2 + Jwt + ElementUi的 RBAC模型管理系统。 主要以自定义拦截器和jwt结合进行权限验证 通过自定义指令实现按钮级别权限,使用经典的RBAC模型 什么是RBAC? 1、RBAC模型概述 RBAC模型(Role-Based Access Control:基于角色的…...

十五届蓝桥杯第三期模拟赛题单(C++、java、Python)

备战2024年蓝桥杯 省赛第三期模拟赛题单 备战Python大学A组 第一题 【问题描述】 请问 2023 有多少个约数?即有多少个正整数,使得 2023 是这个正整数的整数倍。 【问题描述】 这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果…...

嵌入式驱动学习第一周——git的使用

前言 本文主要介绍git的使用,包括介绍git,gitee,以及使用gitee创建仓库并托管代码 嵌入式驱动学习专栏将详细记录博主学习驱动的详细过程,未来预计四个月将高强度更新本专栏,喜欢的可以关注本博主并订阅本专栏&#xf…...

界面控件DevExpress .NET MAUI v23.2新版亮点 - 拥有全新的彩色主题

DevExpress拥有.NET开发需要的所有平台控件,包含600多个UI控件、报表平台、DevExpress Dashboard eXpressApp 框架、适用于 Visual Studio的CodeRush等一系列辅助工具。屡获大奖的软件开发平台DevExpress 今年第一个重要版本v23.1正式发布,该版本拥有众多…...

RAG优化的底层逻辑被推翻!检索质量才是生成效果的核心,90%的人都选错了评估指标

做RAG系统的开发者,几乎都陷入过两个无解的困局: 一是评估成本高到离谱,每次迭代都要跑完整的端到端生成人工/LLM评估,耗时耗力还受大模型随机波动影响; 二是优化方向完全跑偏,疯狂堆迭代检索、多轮反思、子…...

AIAgent仿真环境搭建终极清单(2024Q3最新):覆盖Unity ML-Agents v4.0、Isaac Sim 2024.1、Meta’s Habitat 3.2 兼容矩阵与迁移路径

第一章:AIAgent架构中的仿真环境搭建 2026奇点智能技术大会(https://ml-summit.org) 仿真环境是AIAgent训练与验证的核心基础设施,它需精确复现真实世界的状态演化、动作反馈与多智能体交互逻辑。一个健壮的仿真环境不仅提供高保真物理/逻辑建模能力&am…...

Sunshine开源游戏串流服务器:免费搭建跨平台低延迟游戏共享系统

Sunshine开源游戏串流服务器:免费搭建跨平台低延迟游戏共享系统 【免费下载链接】Sunshine Self-hosted game stream host for Moonlight. 项目地址: https://gitcode.com/GitHub_Trending/su/Sunshine Sunshine是一款开源免费的自托管游戏串流服务器&#x…...

别再死记硬背C#语法了!用5个机器视觉小例子带你快速上手(Visual Studio 2022版)

用5个机器视觉小项目玩转C#语法(Visual Studio 2022实战) 刚接触C#的开发者常陷入语法记忆的泥潭,而机器视觉领域恰好需要快速验证想法的能力。本文将带你用Visual Studio 2022创建五个渐进式图像处理项目,在解决实际问题的过程中…...

光学仿真进阶:利用MATLAB优化贝塞尔高斯光束传输性能的3个技巧

光学仿真进阶:利用MATLAB优化贝塞尔高斯光束传输性能的3个技巧 贝塞尔高斯光束在激光加工、光学镊子和生物成像等领域展现出独特优势,但精确仿真其传输特性往往面临计算效率与精度的双重挑战。许多工程师在完成基础仿真后,常陷入"参数微…...

手把手教你:在MounRiver Studio里为WCH RISC-V芯片切换GCC12工具链(附内存占用对比)

在MounRiver Studio中为WCH RISC-V芯片升级GCC12工具链的完整指南 当你第一次打开MounRiver Studio(MRS)并创建一个WCH RISC-V MCU工程时,系统默认会使用GCC8工具链进行编译。但你可能已经听说,新版的GCC12能带来更好的代码优化效…...

计算机视觉基础模型深度解析:13类算法、85个变种完全指南

计算机视觉基础模型深度解析:13类算法、85个变种完全指南做计算机视觉的兄弟应该知道,标注数据是真tm贵。为了不花这个钱,各路神仙开始用无标注数据、网上爬的图文数据、甚至多模态数据来训练模型。用对比学习、掩码重建这些方法整一个基础模…...

把 CTS 通信目的地一次讲透,TMSADM、TMSSUP、TMSWF 与 CALLTP 的分工、权限与安全边界

很多做 SAP Basis 和 ABAP 运维的人,对 STMS 里那种体验都不陌生,系统概览能看到,导入队列也能看,真到改配置、调队列、做导入时,界面突然弹出目标系统登录框。表面看像是 RFC 权限不完整,真往下追,会发现这不是配置失误,反而是 CTS 故意这样设计的。CTS 并不是只靠一条…...

BP神经网络交叉验证算法与确定最佳隐含层节点数Matlab程序(直接运行、数据Excel格式、...

bp神经网络交叉验证算法和确定最佳隐含层节点个数matlab 程序,直接运行即可。 数据excel格式,注释清楚,效果清晰,一步上手。BP 神经网络交叉验证与隐含层节点自寻优工具包功能说明书一、产品定位本工具包面向“零算法背景”的实验…...

直流无刷减速电机驱动控制的关键技术与安全设计

1. 直流无刷减速电机驱动基础 第一次接触直流无刷减速电机时,我被它安静高效的特性惊艳到了。相比传统有刷电机,这种电机通过电子换相取代了机械电刷,寿命直接提升5-10倍。但真正上手驱动时,发现里面门道比想象中复杂得多。 核心在…...