c語言基于mmap實現的內存池

文章目錄

    • 0. 概要
    • 1. mmap基礎
    • 2. 為什么使用內存池?
    • 3. 使用示例
    • 4. 設計考慮
    • 5. 實現步驟

0. 概要

c語言基于mmap實現的內存池模塊
倉庫地址: https://gitee.com/liudegui/mem_allocator_c

1. mmap基礎

mmap系統調用在進程的虛擬地址空間和某個文件對象或匿名存儲之間建立映射關系。當使用mmap進行內存映射時,操作系統會創建一個映射,使得對這段內存的訪問就像對文件的讀寫一樣。

void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
  • addr:建議的映射起始地址(通常設為NULL,由系統決定)。
  • length:映射區域的長度。
  • prot:期望的內存保護標志(如PROT_READ, PROT_WRITE等)。
  • flags:影響映射區域的各種特性(如MAP_SHARED, MAP_PRIVATE等)。
  • fd:被映射對象的文件描述符,或者使用-1來表示匿名映射。
  • offset:文件映射的起始位置。

2. 為什么使用內存池?

  1. 提高效率:內存池可以減少向操作系統申請和釋放內存的次數,從而提高內存分配的效率。
  2. 減少碎片:內存池可以有效地減少內存碎片,提高內存利用率。
  3. 便于管理:內存池可以將內存的申請、釋放等操作集中管理,方便程序員進行內存調試和維護。

3. 使用示例

下面是一個基于C語言的內存池實現示例:

  • 頭文件mem_allocator_c.h
/***Manager usage of vm mapped to /dev/mem 0x1000000~0x1dfffff*When create a MemPool, it's pool_ should be alloc use this class.*It will first alloc firstly try to alloc from memory map to /dev/mem.*If there is not enough memory in /dev/mem 0x1000000~0x1dfffff, it*will try to call calloc() func of stdlib to alloc memory.*/#ifndef UTILS_MEM_ALLOCATOR_C_H_
#define UTILS_MEM_ALLOCATOR_C_H_#include <stdbool.h>
#include <stdint.h>
#include <unistd.h>
#include <stddef.h>#define MEM_ALLOC_DEFAULT 1
#define MEM_ALLOC_MAP 1
#define MEM_FD_INIT -1//=====================================================================
// MemMapMemAllocator
// Use MemMap to map /dev/mem 0x1000000-0x1dffefff into virtual memory.
// Use a linked table to store ranges in this mapping space. A range
// may be free or in-use.
//=====================================================================typedef struct MemAllocator MemAllocator;
typedef struct MemRange MemRange;
typedef struct MMapParams MMapParams;
typedef struct MemAllocDelegate MemAllocDelegate;#define MMAP_BASE_ADDR 0x10000000
#define MMAP_HIGH_ADDR 0x1DFFEFFFstruct MemRange {int8_t* offset;int8_t* end;uint32_t size;bool is_dirty;MemRange* next;MemRange* pre;
};struct MMapParams {MemRange* range_list;int32_t mem_fd;int8_t* map_base;uint32_t page_size;uint32_t base_addr;uint32_t high_addr;
};struct MemAllocator {int8_t* (*calloc)(MemAllocator* allocator, uint32_t nmemb, uint32_t size);void (*free)(MemAllocator* allocator, int8_t* buffer);char allocator_name[32];MMapParams* mmap_params;MemAllocator* next;
};struct MemAllocDelegate{MemAllocator* allocator;
};void init_mem_delegate(MemAllocDelegate* delegate, uint32_t base_addr, uint32_t high_addr);
int8_t* mem_delegate_calloc(MemAllocDelegate* delegate, uint32_t nmemb, uint32_t size);
void mem_delegate_free(MemAllocDelegate* delegate, int8_t* buffer);
void destroy_mem_delegate(MemAllocDelegate* delegate);#endif  // UTILS_MEM_ALLOCATOR_C_H_
  • 實現代碼見: https://gitee.com/liudegui/mem_allocator_c
#include "mem_allocator_c.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>int main() {printf("hello world");MemAllocDelegate delegate;init_mem_delegate(&delegate, 0, 0);int8_t* p_addr = mem_delegate_calloc(&delegate, 10, 10);const char* const str = "hello world";memcpy(p_addr, str, strlen(str) + 1);printf("%s\n", p_addr);mem_delegate_free(&delegate, p_addr);destroy_mem_delegate(&delegate);return 0;
}

在這個示例中,我們首先定義了一個MemAllocDelegate結構體,用于存儲內存池的信息。然后,我們通過init_mem_delegate函數初始化內存池,指定其大小和對齊要求。接下來,我們使用mem_delegate_calloc函數從內存池中分配一塊內存,并將字符串"hello world"復制到這塊內存中。最后,我們使用mem_delegate_free函數釋放這塊內存,并通過destroy_mem_delegate函數銷毀內存池。

4. 設計考慮

在設計基于mmap的內存池時,需要考慮以下關鍵因素:

  1. 內存映射大小 :確定內存映射的大小是至關重要的。太小可能導致頻繁地創建新的映射,而太大則可能造成內存浪費。
  2. 內存對齊 :確保內存分配滿足特定硬件或軟件的對齊要求。
  3. 內存保護 :設置合理的內存保護標志以避免越界訪問。
  4. 內存清理 :在程序結束時,確保所有映射都被正確地釋放。
  5. 錯誤處理 :正確處理mmap調用可能出現的錯誤,例如內存不足。
  6. 性能監控 :跟蹤內存分配和釋放的性能,以優化內存池的行為。

5. 實現步驟

  1. 初始化
    • 定義內存池結構體,包含必要的字段如mmap_paramsMMapMemAllocator等。
    • 初始化內存映射參數,包括頁大小、映射大小等。
    • 調用mmap創建初始內存映射區域。
  2. 內存分配
    • 實現內存分配邏輯,根據請求的大小找到第一個合適的空閑區域。
    • 更新內存池的數據結構以反映分配情況。
    • 返回分配的內存區域的指針。
  3. 內存釋放
    • 根據提供的指針找到對應的內存區域。
    • 更新內存池的數據結構以標記該區域為可用。
    • 如果有必要,合并相鄰的空閑區域以減少碎片。
  4. 銷毀
    • 遍歷內存池的所有映射區域,調用munmap釋放每個映射。
    • 清理內存池的數據結構。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/18920.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/18920.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/18920.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

doxygen 1.11.0 使用詳解(十四)——輸出格式

目錄 HTMLLATEXMan pagesRTFXMLDocBookCompiled HTML Help (a.k.a. Windows 98 help)Qt Compressed Help (.qch)Eclipse HelpXCode DocSetsPostScriptPDF The following output formats are directly supported by doxygen: HTML Generated if GENERATE_HTML is set to YES i…

時政|共享員工

概念 有人稱“共享員工”就是變相的“勞務派遣”“外包”“臨時工”&#xff0c;是對勞動者的變相壓榨。專家表示&#xff0c;應從根源上理清“共享員工”的概念&#xff0c;否則會破壞正常的勞動合同秩序&#xff0c;無法讓勞動者的合法權益得到有效保障。“共享員工”是指企…

被忽視的模塊化領域:聚合、結算與執行層

原文標題&#xff1a;《Aggregation, settlement, execution》撰文&#xff1a;Bridget Harris 編譯&#xff1a;Chris&#xff0c;Techub News 在關注度和創新方面&#xff0c;模塊化堆棧的各個部分并不一樣&#xff0c;雖然之前有許多項目在數據可用性&#xff08;DA&#xf…

[AI OpenAI] OpenAI董事會成立安全與保障委員會

這個新委員會負責就所有OpenAI項目的關鍵安全和保障決策提出建議&#xff1b;在90天內提出建議。 今天&#xff0c;OpenAI董事會成立了一個由主席Bret Taylor、Adam D’Angelo、Nicole Seligman和Sam Altman&#xff08;CEO&#xff09;領導的安全與保障委員會。該委員會將負責…

MySQL alter 語句

ALTER TABLE user ADD COLUMN cdkey varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT CD-Key, ADD COLUMN erp_userid varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT ERP用戶ID, ADD UNIQUE INDEX un…

虹科Pico汽車示波器 | 免拆診斷案例 | 2017款吉利帝豪GL車發動機偶爾無法起動

故障現象  一輛2017款吉利帝豪GL車&#xff0c;搭載JLC-4G18發動機和手動變速器&#xff0c;累計行駛里程約為39.3萬km。車主反映&#xff0c;該車發動機偶爾無法起動。故障發生頻率比較頻繁&#xff0c;冷機狀態下故障比較容易出現。 故障診斷  接車后試車&#xff0c;故…

【Windows】本地磁盤掛載 Minio 桶

目錄 1.軟件安裝安裝winfsp支持安裝rclone 2.新建rclone遠程存儲類型S3服務類型驗證方式地區終端地址ACL服務端加密KMS 3.掛載存儲盤 1.軟件安裝 安裝winfsp支持 下載地址 或 下載地址2 文件為msi文件&#xff0c;下載后雙擊直接安裝即可&#xff0c;可以選擇安裝路徑 安裝r…

Java多線程——線程強制執行

Join合并線程&#xff0c;待此線程執行完成后&#xff0c;再執行其他線程&#xff0c;其他線程阻塞。 可以想象成插隊。 代碼演示&#xff1a; //測試Join方法 //想象為插隊 public class TestJoin implements Runnable{Overridepublic void run() {for (int i 0; i < 1…

手機號碼攜號轉網查詢保障用戶權益、信息透明、優化用戶體驗

攜號轉網服務是指在同一本地網范圍內&#xff0c;蜂窩移動通信用戶&#xff08;不含物聯網用戶&#xff09;變更簽約的基礎電信業務經營者而用戶號碼保持不變的一項服務。近年來&#xff0c;隨著通信行業的不斷發展&#xff0c;攜號轉網服務已成為滿足用戶個性化需求、提升服務…

Strust2 遠程代碼執行漏洞[s2-005]

漏洞復現環境搭建請參考 http://t.csdnimg.cn/rZ34p kali切換jdk版本請參考 Kali安裝JAVA8和切換JDK版本的詳細過程_kali安裝jdk8-CSDN博客 漏洞原理 Strust2會將http的每個參數名解析成為OGNL語句執行&#xff0c;OGNL表達式通過#來訪問Struts的對象&#xff0c;并且通過過…

JS裁剪圖片底部的水印

效果 源碼 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Image Popup</title><style>…

python dict字典

mapping 對象會將 hashable 值映射到任意對象。 映射屬于可變對象。 目前僅有一種標準映射類型 字典。 &#xff08;關于其他容器對象請參看 list, set 與 tuple 等內置類&#xff0c;以及 collections 模塊。&#xff09; 字典的鍵 幾乎 可以為任何值。 不是 hashable 的值&am…

2024.05.14 校招 實習 內推 面經

綠*泡*泡VX&#xff1a; neituijunsir 交流*裙 &#xff0c;內推/實習/校招匯總表格 1、校招 | 中核集團2025屆校園招聘提前批正式啟動&#xff01; 校招 | 中核集團2025屆校園招聘提前批正式啟動&#xff01; 2、實習 | 嵐圖汽車校園實習生招聘 實習 | 嵐圖汽車校園實習生…

達夢 結果拼接=多行結果返回一列字符串.

sql 轉換 查詢出多行數據 (select t.PROPERTY from JD_CODING t left join DELIVERY_OF c on t.VALUE c.TYPE where t.PROPERTY stackingType group by t.PROPERTY) 更改后 轉為一列的拼接字符串 ( select listagg( distinct t.PROPERTY,,) within group ( order by t.P…

MiniPCIe/SATA雙用插槽無法識別minipcie模塊怎么回事!

在計算機和嵌入式系統設計中,MiniPCIe/SATA雙用插槽作為一種高度集成的解決方案,提供了極大的靈活性與擴展能力。它不僅能夠支持MiniPCIe接口的無線網卡、固態硬盤控制器等模塊,還能適應SATA接口的硬盤或固態存儲設備,大大豐富了系統配置的可能性。盡管設計初衷良好,但在實…

bert模型用于二分類問題微調

使用bert-base-chinese預訓練模型對二分類問題進行微調 import pandas as pd from transformers import BertTokenizerFast, AutoModelForSequenceClassification, Trainer, TrainingArguments import torchmodel_name "./bert-base-chinese" path "./abuse_…

STP19NF20 絲印 19NF20 場效應管19A 200V 直插 TO-220

STP19NF20 功率MOSFET的應用領域相當廣泛&#xff0c;主要包括&#xff1a; 1. 電源管理&#xff1a;用于高效率電源管理電路&#xff0c;如直流-直流轉換器和交流-直流電源適配器。 2. 開關模式電源&#xff08;SMPS&#xff09;&#xff1a;在需要高效能和緊湊型尺寸的開關…

Ceph相關命令

關于osd自動重啟 /etc/crontab里面每隔2分鐘會調用 /etc/cron.daily/keep_osd.sh關閉osd 1 mv /etc/cron.daily/keep_osd.sh /etc/cron.daily/keep_osd.sh_back 2 systemctl stop ceph-osd0.service查看osd的參數 ceph daemon osd.0 config show |grep osd_op_num動態修改…

【學習】軟件測試小伙伴,這幾點助你提升軟件測試水平

在數字化時代&#xff0c;軟件已經無處不在&#xff0c;影響著我們的日常生活、工作乃至整個社會的運行。在這個背景下&#xff0c;軟件測試成為確保產品質量的關鍵環節&#xff0c;關乎用戶體驗和社會信任。本文將為您梳理一些關于軟件測試你必須了解的知識點&#xff0c;并闡…

JAVAEE之多線程進階(2)_ CAS概念、實現原理、ABA問題及解決方案

前言 在并發編程時&#xff0c;常常會出現線程安全問題&#xff0c;那么如何保證原子性呢&#xff1f;常用的方法就是加鎖。在Java語言中可以使用 Synchronized和CAS實現加鎖效果。 ?Synchronized關鍵字保證同步的&#xff0c;這會導致有鎖&#xff0c;但是鎖機制存在以下問題…