【操作系統】內存泄漏 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.pswp.cn/bicheng/75103.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/75103.shtml
英文地址,請注明出處:http://en.pswp.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…