【操作系统】内存泄漏 vs 内存碎片

【操作系统】内存泄漏 vs 内存碎片

  • 内存泄漏(Memory Leak) vs 内存碎片(Memory Fragmentation)
    • 1. 内存泄漏(Memory Leak)
    • 2. 内存碎片(Memory Fragmentation)
    • 3. 内存泄漏 vs 内存碎片对比
    • 4. 实际案例
      • 内存泄漏案例(Web 服务器)
      • 内存碎片案例(游戏引擎)
    • 5. 最佳实践
      • 避免内存泄漏
      • 减少内存碎片
    • 6. 总结
    • 7. 其他
      • 7.1 为什么linux不容易出现内存碎片化?
      • 7.2 内存的类型

内存泄漏(Memory Leak) vs 内存碎片(Memory Fragmentation)

内存泄漏和内存碎片是内存管理的两个关键问题,它们都会影响程序性能和稳定性,但成因和表现不同。


1. 内存泄漏(Memory Leak)

定义
内存泄漏 是指程序 申请了内存但未正确释放,导致这部分内存无法被系统回收,最终可能耗尽可用内存。

原因

  • 忘记释放动态分配的内存(如 malloc() 后没有 free())。
  • 指针丢失(如指针被重新赋值,导致原内存无法访问)。
  • 循环引用(如两个对象互相引用,垃圾回收器无法回收)。
  • 异常或提前退出(如 malloc() 后程序崩溃,未执行 free())。

影响

  • 短期:程序占用内存逐渐增加。
  • 长期:系统可用内存减少,可能导致 OOM(Out of Memory) 崩溃。

示例(C 语言)

void leak_example() {int *ptr = malloc(100 * sizeof(int)); // 分配内存// 忘记 free(ptr),内存泄漏!
}

检测与解决

  • 工具
    • Valgrind(Linux):检测内存泄漏。
    • AddressSanitizer (ASan)(GCC/Clang):运行时检测。
    • Windows CRT Debug Heap_CrtDumpMemoryLeaks())。
  • 最佳实践
    • RAII(Resource Acquisition Is Initialization)(C++ 智能指针 std::unique_ptrstd::shared_ptr)。
    • 手动管理内存时,确保 malloc/freenew/delete 成对使用

2. 内存碎片(Memory Fragmentation)

定义
内存碎片 是指内存被分割成许多小块,导致 虽有足够总内存,但无法分配连续大块内存

类型

  1. 外部碎片(External Fragmentation)

    • 空闲内存分散,无法合并成大块。
    • 例如:多次 mallocfree 后,剩余内存变成“碎片”。
  2. 内部碎片(Internal Fragmentation)

    • 分配的内存比实际需求大(如对齐要求)。
    • 例如:malloc(10) 可能实际占用 16 字节(由于内存对齐)。

原因

  • 堆不足、资源不足
  • 频繁动态内存分配/释放(如游戏、长期运行的服务)。
  • 内存分配策略问题(如 mallocglibc 实现可能产生碎片)。

影响

  • 分配失败:即使总内存足够,malloc 可能失败(无法找到连续内存)。
  • 性能下降:内存访问变慢(缓存不友好)。

示例

void frag_example() {void *p1 = malloc(100); // 分配 100 字节void *p2 = malloc(100); // 再分配 100 字节free(p1);               // 释放 p1// 现在有 100 字节空闲,但可能无法分配 200 字节(碎片化)void *p3 = malloc(200); // 可能失败!
}

解决内存碎片

  • 内存池(Memory Pool)
    • 预分配大块内存,避免频繁 malloc/free
    • 适用于固定大小的对象(如游戏中的粒子系统)。
  • 紧凑(Compaction)
    • 移动内存块,合并空闲区域(某些 GC 语言如 Java 会做)。
  • 使用 slab 分配器(Linux 内核):
    • 针对不同大小的对象优化分配。
  • 避免频繁小内存分配
    • 使用对象池或缓存。

3. 内存泄漏 vs 内存碎片对比

特性内存泄漏内存碎片
根本问题内存未释放,无法回收内存被分割,无法分配连续大块内存
表现内存占用持续增长malloc 失败,即使总内存足够
检测工具Valgrind、ASan、LeakSanitizer内存分析工具(如 pmapjemalloc
解决方案确保 free/delete,使用智能指针内存池、slab 分配器、减少碎片分配
影响范围整个进程崩溃(OOM)特定分配失败,性能下降

4. 实际案例

内存泄漏案例(Web 服务器)

void handle_request() {char *buffer = malloc(1024); // 每个请求分配内存// 处理请求...// 忘记 free(buffer),每次请求泄漏 1KB!
}

后果:服务器运行时间越长,内存占用越高,最终崩溃。

内存碎片案例(游戏引擎)

void update_particles() {for (int i = 0; i < 1000; i++) {Particle *p = malloc(sizeof(Particle)); // 频繁分配/释放// 更新粒子...free(p);}
}

后果:运行一段时间后,malloc 失败,游戏卡死。


5. 最佳实践

避免内存泄漏

Cmalloc 后必须 free,使用 valgrind 检测。
C++:优先使用 std::unique_ptrstd::shared_ptr
Java/Python:避免循环引用,关注 GC 日志。

减少内存碎片

使用内存池(如 C++ boost::pool)。
减少频繁小内存分配(如预分配数组)。
选择合适的内存分配器(如 jemalloctcmalloc)。

6. 总结

  • 内存泄漏未释放内存 → 用工具检测,确保释放。
  • 内存碎片分配失败 → 用内存池或优化分配策略。
  • 关键:合理管理内存,结合工具分析,避免长期运行问题!

7. 其他

7.1 为什么linux不容易出现内存碎片化?

  1. MMU(CPU-(虚拟地址)->MMU-(物理地址)->内存)
  2. RAM很大
  3. Linux有成熟的内存管理算法(Buddy算法、Slab算法)

7.2 内存的类型

  1. 大块的内存申请
  2. 生命周期很长的内存块
  3. 生命周期很短的小内存块

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

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

相关文章

力扣HOT100之矩阵:73. 矩阵置零

这道题我没有想到什么好的办法&#xff0c;直接暴力AC了&#xff0c;直接遍历两次矩阵&#xff0c;第一次遍历用两个向量分别记录出现0的行数和列数&#xff0c;第二次遍历就判断当前的元素的行数或者列数是否出现在之前的两个向量中&#xff0c;若出现了就直接置零&#xff0c…

​Flink/Kafka在python中的用处

一、基础概念 1. ​Apache Kafka 是什么&#xff1f; ​核心功能&#xff1a;Kafka 是一个分布式流处理平台&#xff0c;主要用于构建实时数据管道和流式应用程序。​核心概念&#xff1a; ​生产者&#xff08;Producer&#xff09;​&#xff1a;向 Kafka 发送数据的程序。…

推荐系统(十八):优势特征蒸馏(Privileged Features Distillation)在商品推荐中的应用

在商品推荐系统中&#xff0c;粗排和精排环节的知识蒸馏方法主要通过复杂模型&#xff08;Teacher&#xff09;指导简单模型&#xff08;Student&#xff09;的训练&#xff0c;以提升粗排效果及与精排的一致性。本文将以淘宝的一篇论文《Privileged Features Distillation at …

深度学习四大核心架构:神经网络(NN)、卷积神经网络(CNN)、循环神经网络(RNN)与Transformer全概述

目录 &#x1f4c2; 深度学习四大核心架构 &#x1f330; 知识点概述 &#x1f9e0; 核心区别对比表 ⚡ 生活化案例理解 &#x1f511; 选型指南 &#x1f4c2; 深度学习四大核心架构 第一篇&#xff1a; 神经网络基础&#xff08;NN&#xff09; &#x1f330; 知识点概述…

R语言对偏态换数据进行转换(对数、平方根、立方根)

我们进行研究的时候经常会遇见偏态数据&#xff0c;数据转换是统计分析和数据预处理中的一项基本技术。使用 R 时&#xff0c;了解如何正确转换数据有助于满足统计假设、标准化分布并提高分析的准确性。在 R 中实现和可视化最常见的数据转换&#xff1a;对数、平方根和立方根转…

第十四届蓝桥杯省赛电子类单片机学习记录(客观题)

01.一个8位的DAC转换器&#xff0c;供电电压为3.3V&#xff0c;参考电压2.4V&#xff0c;其ILSB产生的输出电压增量是&#xff08;D&#xff09;V。 A. 0.0129 B. 0.0047 C. 0.0064 D. 0.0094 解析&#xff1a; ILSB&#xff08;最低有效位&#xff09;的电压增量计算公式…

HarmonyOSNext_API16_媒体查询

媒体查询条件详解 媒体查询是响应式设计的核心工具&#xff0c;通过判断设备特征动态调整界面样式。其完整规则由媒体类型、逻辑操作符和媒体特征三部分组成&#xff0c;具体解析如下&#xff1a; 一、媒体查询语法结构 基本格式&#xff1a; [媒体类型] [逻辑操作符] (媒体特…

Python+拉普拉斯变换求解微分方程

引言 在数学和工程学中,微分方程广泛应用于描述动态系统的行为,如电路、电气控制系统、机械振动等。求解微分方程的一个常见方法是使用拉普拉斯变换,尤其是在涉及到初始条件时。今天,我们将通过 Python 演示如何使用拉普拉斯变换来求解微分方程,并帮助大家更好地理解这一…

【算法】手撕快速排序

快速排序的思想 任取一个元素作为枢轴&#xff0c;然后想办法把这个区间划分为两部分&#xff0c;小于等于枢轴的放左边&#xff0c;大于等于枢轴的放右边 然后递归处理左右区间&#xff0c;直到空或只剩一个 具体动画演示详见 数据结构合集 - 快速排序(算法过程, 效率分析…

《八大排序算法》

相关概念 排序&#xff1a;使一串记录&#xff0c;按照其中某个或某些关键字的大小&#xff0c;递增或递减的排列起来。稳定性&#xff1a;它描述了在排序过程中&#xff0c;相等元素的相对顺序是否保持不变。假设在待排序的序列中&#xff0c;有两个元素a和b&#xff0c;它们…

深度学习篇---paddleocr正则化提取

文章目录 前言一、代码总述&介绍1.1导入必要的库1.1.1cv21.1.2re1.1.3paddleocr 1.2初始化PaddleOCR1.3打开摄像头1.4使用 PaddleOCR 进行识别1.5定义正则表达式模式1.6打印提取结果1.7异常处理 二、正则表达式2.1简介2.2常用正则表达式模式及原理2.2.1. 快递单号模式2.2.2…

JavaScript DOM与元素操作

目录 DOM 树、DOM 对象、元素操作 一、DOM 树与 DOM 对象 二、获取 DOM 元素 1. 基础方法 2. 现代方法&#xff08;ES6&#xff09; 三、修改元素内容 四、修改元素常见属性 1. 标准属性 2. 通用方法 五、通过 style 修改样式 六、通过类名修改样式 1. className 属…

单元测试的编写

Python 单元测试示例 在 Python 中&#xff0c;通常使用 unittest 模块来编写单元测试。以下是一个简单的示例&#xff1a; 示例代码&#xff1a;calculator.py # calculator.py def add(a, b):return a bdef subtract(a, b):return a - b 单元测试代码&#xff1a;test_c…

大模型学习:从零到一实现一个BERT微调

目录 一、准备阶段 1.导入模块 2.指定使用的是GPU还是CPU 3.加载数据集 二、对数据添加词元和分词 1.根据BERT的预训练&#xff0c;我们要将一个句子的句头添加[CLS]句尾添加[SEP] 2.激活BERT词元分析器 3.填充句子为固定长度 代码解释&#xff1a; 三、数据处理 1.…

10组时尚复古美学自然冷色调肖像电影照片调色Lightroom预设 De La Mer – Nautical Lightroom Presets

De La Mer 预设系列包含 10 种真实的调色预设&#xff0c;适用于肖像、时尚和美术。为您的肖像摄影带来电影美学和个性&#xff01; De La Mer 预设非常适合专业人士和业余爱好者&#xff0c;可在桌面或移动设备上使用&#xff0c;为您的摄影项目提供轻松的工作流程。这套包括…

SDL多窗口多线程渲染技术解析

SDL多窗口多线程渲染技术解析 技术原理 SDL多线程模型与窗口管理 SDL通过SDL_Thread结构体实现跨平台线程管理。在多窗口场景中,每个窗口需关联独立的渲染器,且建议遵循以下原则: 窗口与渲染器绑定:每个窗口创建时生成专属渲染器(SDL_CreateRenderer),避免跨线程操作…

QT 跨平台发布指南

一、Windows 平台发布 1. 使用 windeployqt 工具 windeployqt --release --no-compiler-runtime your_app.exe 2. 需要包含的文件 应用程序 .exe 文件 Qt5Core.dll, Qt5Gui.dll, Qt5Widgets.dll 等 Qt 库 platforms/qwindows.dll 插件 styles/qwindowsvistastyle.dll (如果使…

L2-037 包装机 (分数25)(详解)

题目链接——L2-037 包装机 问题分析 这个题目就是模拟了物品在传送带和筐之间的传送过程。传送带用队列模拟&#xff0c;筐用栈模拟。 输入 3 4 4 GPLT PATA OMSA 3 2 3 0 1 2 0 2 2 0 -1输出 根据上述操作&#xff0c;输出的物品顺序是&#xff1a; MATA样例分析 初始…

机器学习的一百个概念(4)下采样

前言 本文隶属于专栏《机器学习的一百个概念》&#xff0c;该专栏为笔者原创&#xff0c;引用请注明来源&#xff0c;不足和错误之处请在评论区帮忙指出&#xff0c;谢谢&#xff01; 本专栏目录结构和参考文献请见[《机器学习的一百个概念》 ima 知识库 知识库广场搜索&…

qt6下配置qopengl

qt部件选择 Qt 6&#xff1a;需要手动选择 Qt Shader Tools 和 Qt 5 Compatibility Module&#xff08;如果需要兼容旧代码&#xff09; cmake文件 cmake_minimum_required(VERSION 3.16) # Qt6 推荐最低 CMake 3.16 project(myself VERSION 0.1 LANGUAGES CXX)set(CMAKE_A…