程序语言的内存管理:垃圾回收GC(Java)、手动管理(C语言)与所有权机制(Rust)(手动内存管理、手动管理内存)
文章目录
- 程序语言的内存管理:垃圾回收、手动管理与所有权机制
- 引言
- 一、垃圾回收机制(GC)(Java)
- 1. 什么是垃圾回收机制
- 2. 垃圾回收的工作原理
- 3. 优点与缺点
- 4. 示例代码
- 二、手动管理内存的分配和释放(C语言)
- 1. 手动内存管理的概念
- 2. 手动内存管理的优缺点
- 3. 示例代码
- 注意事项
- 4. 常见错误示例
- 1. 忘记释放内存(内存泄漏)
- 2. 重复释放内存(未定义行为)
- 3. 释放未分配的内存(未定义行为)
- 5. 内存管理的良好实践
- 三、通过所有权来管理内存(Rust)
- 1. 所有权机制的概念
- 2. 所有权规则
- - 每个值有且只有一个所有者。
- - 值在任一时刻只能有一个可变引用,或多个不可变引用。
- - 当所有者离开作用域,值被丢弃,内存释放。
- 3. 优点与缺点
- 4. 示例代码
- 结论
程序语言的内存管理:垃圾回收、手动管理与所有权机制
引言
在现代计算机科学中,内存管理是编程语言设计中的核心问题之一。如何有效地申请、使用和释放内存,直接影响程序的性能和可靠性。在计算机语言的演变过程中,出现了三种主要的内存管理方式:
- 垃圾回收机制(GC):程序运行时自动寻找不再使用的内存进行回收。
- 手动管理内存的分配和释放:程序员通过函数调用的方式手动控制内存的申请和释放。
- 通过所有权来管理内存:编译器在编译时根据所有权规则检查并管理内存。
本文将深入探讨这三种内存管理方式的原理、优缺点,并提供相应的示例代码。
一、垃圾回收机制(GC)(Java)
1. 什么是垃圾回收机制
垃圾回收(Garbage Collection,GC)是一种自动内存管理技术。它的核心思想是在程序运行时,由垃圾回收器自动监控内存的使用情况,识别不再被引用的对象,并回收其占用的内存空间。
2. 垃圾回收的工作原理
垃圾回收器通常采用以下两种算法:
- 引用计数(Reference Counting):为每个对象维护一个引用计数,当计数为零时回收该对象。
- 标记-清除(Mark and Sweep):遍历所有可达对象,标记它们为活动的,未被标记的对象即为垃圾,随后清除。
3. 优点与缺点
优点:
- 简化内存管理:程序员无需显式地释放内存,减少了内存泄漏和悬挂指针的风险。
- 提高开发效率:专注于业务逻辑,而非内存管理。
缺点:
- 性能开销:垃圾回收会占用一定的CPU时间,可能导致程序暂停(Stop-The-World)。
- 不可预测的延迟:垃圾回收的触发时机和持续时间不可控,可能影响实时性要求高的应用。
4. 示例代码
以下是Java中的一个示例:
public class GarbageCollectionExample {public static void main(String[] args) {// 创建对象Object obj = new Object();// 对象不再被引用obj = null;// 建议JVM进行垃圾回收System.gc();}
}
在上述代码中,对象obj在赋值为null后,不再有任何引用,垃圾回收器会在适当的时候回收该对象。
二、手动管理内存的分配和释放(C语言)
1. 手动内存管理的概念
在C语言中,内存管理完全依赖程序员手动控制。通过标准库函数malloc、calloc、realloc来动态分配内存,使用free函数来释放已分配的内存。这种方式要求程序员在适当的时机显式地释放不再需要的内存,以防止内存泄漏。
2. 手动内存管理的优缺点
优点:
- 高性能:内存的分配和释放完全由程序员控制,没有垃圾回收的额外开销。
- 灵活性:可以根据特定需求精细地控制内存的使用和优化。
缺点:
- 容易出错:忘记释放内存会导致内存泄漏,错误地释放内存可能引发程序崩溃或未定义行为。
- 增加复杂度:需要手动追踪每一块动态内存的生命周期,增加了编程复杂度和维护成本。
3. 示例代码
以下是C语言中的一个示例:
#include <stdio.h>
#include <stdlib.h>typedef struct {int data;
} MyStruct;int main() {// 手动申请内存MyStruct* ptr = (MyStruct*)malloc(sizeof(MyStruct));if (ptr == NULL) {fprintf(stderr, "内存分配失败\n");return 1;}// 使用对象ptr->data = 42;printf("Data: %d\n", ptr->data);// 手动释放内存free(ptr);return 0;
}
在上述代码中:
- 内存分配:使用
malloc函数动态分配内存,返回一个void*指针,需要强制类型转换为目标类型的指针。 - 空指针检查:在使用分配的内存之前,必须检查指针是否为
NULL,以确保内存分配成功。 - 使用内存:通过指针访问和修改数据。
- 释放内存:使用
free函数释放之前分配的内存,避免内存泄漏。
注意事项
-
匹配分配和释放:每一块通过
malloc、calloc或realloc分配的内存,都必须使用free释放,且只能释放一次。 -
避免非法访问:在释放内存后,指针会变成悬空指针,继续使用会导致未定义行为。建议将指针置为
NULL。free(ptr); ptr = NULL; -
内存泄漏检测:在大型程序中,手动追踪每一块内存可能较为困难。可以使用工具如Valgrind来检测内存泄漏。
4. 常见错误示例
1. 忘记释放内存(内存泄漏)
char* buffer = (char*)malloc(1024);
// 使用buffer
// ...
// 忘记调用free(buffer);
2. 重复释放内存(未定义行为)
int* numbers = (int*)malloc(10 * sizeof(int));
free(numbers);
free(numbers); // 错误:重复释放
3. 释放未分配的内存(未定义行为)
int* ptr;
// 未分配内存
free(ptr); // 错误:ptr未初始化
5. 内存管理的良好实践
- 初始化指针:声明指针时将其初始化为
NULL。 - 及时释放:在不再需要内存时,尽快调用
free。 - 指针置空:在释放内存后,将指针置为
NULL,防止悬空指针。 - 使用工具检测:利用内存分析工具检测内存泄漏和非法访问。
通过在C语言中手动管理内存,程序员可以精确控制内存的使用,但也需要承担管理内存的责任。遵循良好的编程实践,可以减少内存相关的错误,编写出更可靠的代码。
三、通过所有权来管理内存(Rust)
1. 所有权机制的概念
所有权机制是一种在编译时进行内存管理的方式,最典型的代表是Rust语言。每个值都有一个所有者(变量),当所有者离开其作用域时,值会被自动释放。
2. 所有权规则
- 每个值有且只有一个所有者。
- 值在任一时刻只能有一个可变引用,或多个不可变引用。
- 当所有者离开作用域,值被丢弃,内存释放。
3. 优点与缺点
优点:
- 内存安全:在编译期防止了空悬指针和数据竞争等问题。
- 无运行时开销:不需要垃圾回收器,性能高效。
缺点:
- 学习曲线陡峭:需要理解所有权、借用等概念。
- 可能影响开发速度:编译器的严格检查可能导致更多的编译错误。
4. 示例代码
以下是Rust中的一个示例:
fn main() {{let s = String::from("hello");// s 在此作用域内有效}// 离开作用域,s 被自动释放
}
在上述代码中,字符串s在其作用域结束时自动被释放,无需显式地调用任何内存释放函数。
结论
内存管理是编程语言设计和程序开发中的关键问题。垃圾回收机制、手动内存管理和所有权机制各有优缺点:
- 垃圾回收机制简化了内存管理,但可能带来性能开销。
- 手动内存管理提供了最高的性能和灵活性,但增加了出错的风险。
- 所有权机制在保证内存安全的同时提供了高性能,但需要适应新的编程范式。
选择哪种内存管理方式,应根据具体的应用场景和需求进行权衡。在高性能和安全性要求严格的领域,所有权机制可能是最佳选择;在开发效率和简便性方面,垃圾回收机制更具优势;而在需要精细控制内存的场景下,手动内存管理仍然不可替代。
相关文章:
程序语言的内存管理:垃圾回收GC(Java)、手动管理(C语言)与所有权机制(Rust)(手动内存管理、手动管理内存)
文章目录 程序语言的内存管理:垃圾回收、手动管理与所有权机制引言一、垃圾回收机制(GC)(Java)1. 什么是垃圾回收机制2. 垃圾回收的工作原理3. 优点与缺点4. 示例代码 二、手动管理内存的分配和释放(C语言&…...
研究生论文学习记录
文献检索 检索论文的网站 知网:找论文,寻找创新点paperswithcode :这个网站可以直接找到源代码 直接再谷歌学术搜索 格式:”期刊名称“ 关键词 在谷歌学术搜索特定期刊的关键词相关论文,可以使用以下几种方法&#…...
毕业设计选题:基于Django+Vue的图书馆管理系统
开发语言:Python框架:djangoPython版本:python3.7.7数据库:mysql 5.7数据库工具:Navicat11开发软件:PyCharm 系统展示 系统首页 图书馆界面 图书信息界面 个人中心界面 后台登录界面 管理员功能界面 用户…...
#网络安全#NGSOC与传统SOC的区别
NGSOC是Next Generation Security Operation Center(下一代安全运营中心)的缩写。 NGSOC安全运营服务基于态势感知与安全运营平台来开展监测分析等一系列的服务工作,旨在通过专业、高效的运营服务工作,帮助用户尽可能发挥NGSOC作…...
GCN+BiLSTM多特征输入时间序列预测(Pytorch)
目录 效果一览基本介绍程序设计参考资料 效果一览 基本介绍 GCNBiLSTM多特征输入时间序列预测(Pytorch) 可以做风电预测,光伏预测,寿命预测,浓度预测等。 Python代码,基于Pytorch编写 1.多特征输入单步预测…...
LinkedList和链表之刷题课(下)
1. 给定x根据x把链表分割,大的结点放在x后面,小的结点放在x前面 题目解析: 注意此时的pHead就是head(头节点的意思) 基本上就是给定一个链表,我们根据x的值来把这个链表分成俩部分,大的那部分放在x后面,小的那部分放在x前面,并且我们不能改变链表本来的顺序,比如下面的链表,我…...
ollama 在 Linux 环境的安装
ollama 在 Linux 环境的安装 介绍 他的存在在我看来跟 docker 的很是相似,他把市面上已经存在的大语言模型集合在一个仓库中,然后通过 ollama 的方式来管理这些大语言模型 下载 # 可以直接通过 http 的方式吧对应的 shell 脚本下载下来,然…...
C语言二刷指针篇
&取得变量的地址 printf("%p\n", &a); printf("%p\n", a); printf("%p\n", &a[0]); printf("%p\n", &a[1]); 前三个输出相同,a[0]和a[1]之间相差4 指针就是保存地址的变量,指针里放的是别的…...
LeetCode题练习与总结:回文对--336
一、题目描述 给定一个由唯一字符串构成的 0 索引 数组 words 。 回文对 是一对整数 (i, j) ,满足以下条件: 0 < i, j < words.length,i ! j ,并且words[i] words[j](两个字符串的连接)是一个回文…...
CesiumJS 案例 P7:添加指定长宽的图片图层(原点分别为图片图层的中心点、左上角顶点、右上角顶点、左下角顶点、右下角顶点)
CesiumJS CesiumJS API:https://cesium.com/learn/cesiumjs/ref-doc/index.html CesiumJS 是一个开源的 JavaScript 库,它用于在网页中创建和控制 3D 地球仪(地图) 一、添加指定长宽的图片图层(原点为图片图层的中心…...
Redis 主从同步 问题
前言 相关系列 《Redis & 目录》(持续更新)《Redis & 主从同步 & 源码》(学习过程/多有漏误/仅作参考/不再更新)《Redis & 主从同步 & 总结》(学习总结/最新最准/持续更新)《Redis &a…...
【SQL Server】探讨 IN 和 EXISTS之间的区别
前言 在使用 SQL 查询相关表数据时,通常需要根据另一个表中的值来筛选数据。而 IN 与 EXISTS 子句都是用于此场景的常用方式,但使用时两者存在工作方式不同。它们使用上的选择会显著影响查询的性能,尤其是在大型数据集中。本文我们一起探讨 IN 和 EXISTS 之间的区别、使用与…...
清理pip和conda缓存
当用户目录没有空间时,可清理pip和conda缓存 清理conda缓存: conda clean --all清理pip缓存: pip cache purgeNote: 可以利用软链接,将用户目录下的文件链接到其他位置 首先移动文件或文件夹到其他位置 mv ~/test /…...
git rebase和merge的区别
Git merge和Git rebase是两种不同的合并策略,它们在处理分支合并时有各自的优点和缺点。 Git fetch git fetch 命令用于从远程仓库获取最新的更改,但不会自动合并这些更改到你的本地分支。它会下载远程仓库的所有分支和标签,并更新你的本地…...
【elkb】linux麒麟v10安装ELKB 8.8.X版本(ARM架构)
下载软件 相关版本信息 elasticsearch:8.8.1kibana:8.8.1logstash:8.8.1filebeat:8.8.1 下载地址 https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-8.8.1-linux-aarch64.tar.gzhttps://artifacts.elastic…...
bluez hid host介绍,连接键盘/鼠标/手柄不是梦,安排
零. 前言 由于Bluez的介绍文档有限,以及对Linux 系统/驱动概念、D-Bus 通信和蓝牙协议都有要求,加上网络上其实没有一个完整的介绍Bluez系列的文档,所以不管是蓝牙初学者还是蓝牙从业人员,都有不小的难度,学习曲线也相对较陡,所以我有了这个想法,专门对Bluez做一个系统…...
GPT打数模——电商品类货量预测及品类分仓规划
背景 电商企业在各区域的商品存储主要由多个仓库组成的仓群承担。其中存储的商品主要按照属性(品类、件型等)进行划分和打标,便于进行库存管理。图 1 是一个简化的示意图,商品品类各异,件数众多,必须将这些…...
华为OD机试 - 螺旋数字矩阵 - 矩阵(Python/JS/C/C++ 2024 D卷 100分)
华为OD机试 2024E卷题库疯狂收录中,刷题点这里 专栏导读 本专栏收录于《华为OD机试真题(Python/JS/C/C)》。 刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,…...
分类预测 | GCN图卷积神经网络多特征分类预测(MATLAB)
分类预测 | GCN图卷积神经网络多特征分类预测(MATLAB) 目录 分类预测 | GCN图卷积神经网络多特征分类预测(MATLAB)分类效果基本介绍程序设计参考资料分类效果 基本介绍 GCN图卷积神经网络多特征分类预测(MATLAB) 在图卷积神经网络(GCN)中,多特征分类...
FPGA搭建PCIE3.0通信架构简单读写测试,基于XDMA中断模式,提供3套工程源码和技术支持
目录 1、前言工程概述免责声明 2、相关方案推荐我已有的PCIE方案本博客方案的PCIE2.0版本 3、PCIE基础知识4、工程详细设计方案工程设计原理框图XDMA配置及使用XDMA中断模块数据缓存架构用户逻辑Windows版本XDMA驱动安装Linux版本XDMA驱动安装测试应用程序工程源码架构PCIE上板…...
数据标注平台搭建:支持主动学习的智能标注工具
在软件测试领域,测试数据的质量直接决定了测试覆盖率和缺陷发现能力。随着AI驱动测试的兴起,高质量标注数据成为训练测试预言、缺陷预测模型、自动化测试脚本生成等智能测试工具的核心资产。然而,传统的人工标注方式效率低下、一致性差&#…...
从MATLAB验证到RTL实现:一个完整华莱士树乘法器的设计、仿真与调试实战
从MATLAB验证到RTL实现:一个完整华莱士树乘法器的设计、仿真与调试实战 在数字信号处理、图形渲染和密码学等高性能计算领域,乘法器的效率往往成为系统瓶颈。传统阵列乘法器虽然结构规整,但随着位宽增加,其线性增长的延迟特性难以…...
告别Navicat后,我用DBeaver的这10个设置让效率翻倍(含豆沙绿护眼教程)
从Navicat到DBeaver:10个高效设置与健康护眼方案 当公司技术栈调整要求从Navicat迁移到DBeaver时,许多数据库开发者面临的不仅是工具切换,更是工作习惯的重构。作为一款开源的多数据库管理工具,DBeaver在功能深度和可定制性上其实…...
三菱FX3U串口通讯无协议编程与RS指令实现Modbus协议
引言 在工业自动化系统中,PLC与上位机之间的通讯至关重要。Modbus RTU协议 作为一种广泛应用的通讯协议,通常用于不同设备之间的数据交换。 对于三菱 FX3U系列PLC 来说,虽然它没有直接内置完整的Modbus RTU从站功能(早期型号需通过…...
3个关键场景解析:如何使用iperf3 Windows版精准诊断网络性能问题
3个关键场景解析:如何使用iperf3 Windows版精准诊断网络性能问题 【免费下载链接】iperf3-win-builds iperf3 binaries for Windows. Benchmark your network limits. 项目地址: https://gitcode.com/gh_mirrors/ip/iperf3-win-builds 在当今数字化时代&…...
嵌入式系统功耗测量实战:从基础原理到精准优化
1. 功耗测量:从概念到实践的核心挑战 在电子设计领域,无论你面对的是指尖大小的可穿戴设备,还是驱动工厂产线的重型电机,功耗都是一个绕不开的核心议题。我们常说的“功耗”,本质上是一个系统在单位时间内消耗的能量。…...
《线性代数思维》:以代码和案例开启线性代数实用学习之旅!
《线性代数思维》介绍《线性代数思维》以代码为先导、以案例为基础,介绍了线性代数中最常用的概念,专为那些想理解并应用这些概念,而非仅抽象学习的读者设计。每一章都围绕一个现实世界的问题展开,如模拟网络流量、仿真鸟群飞行或…...
带fp8激活量化的RMSNorm算子手撕
rms_norm_fp8_noweight_fp16:计算流程与优化 完整代码 void rms_norm_fp8_noweight_fp16(const __half *x, __nv_fp8_e4m3 *out,int seq_len, int dim, const float *d_scale,cudaStream_t stream) {rms_norm_fp8_noweight_kernel<<<seq_len, 256, 0, stream>&g…...
机器人导航中的深度估计与SLAM技术实践
1. 机器人导航中的深度估计技术解析深度估计作为计算机视觉领域的核心技术,在机器人自主导航中扮演着关键角色。简单来说,它就像给机器人安装了一双能感知距离的"眼睛"——通过分析摄像头捕获的二维图像,计算出场景中每个像素点与相…...
别再被POI内存溢出坑了!手把手教你用EasyExcel 2.1.6搞定百万级数据导入导出
百万级Excel处理实战:从POI到EasyExcel的无痛迁移指南 当业务数据量从几千条膨胀到百万级时,许多Java开发者会发现原本运行良好的POI导出功能突然变成了系统性能的"阿喀琉斯之踵"。我曾亲眼见证一个生产系统在月度报表生成时因OOM崩溃…...
