日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > windows >内容正文

windows

zephyr 系统--- 内存池使用方法

發(fā)布時(shí)間:2024/4/18 windows 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 zephyr 系统--- 内存池使用方法 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

內(nèi)存池(memory pool) 是一個(gè)內(nèi)核對(duì)象,它允許從指定的內(nèi)存區(qū)域上動(dòng)態(tài)地分配內(nèi)存塊(memory block)。同一個(gè)內(nèi)存池中的內(nèi)存塊的大小是不固定的,這樣可以減小由于不同的應(yīng)用程序需要為大小不同的數(shù)據(jù)結(jié)構(gòu)分配不同的存儲(chǔ)空間所造成的浪費(fèi)。內(nèi)存池使用“伙伴(buddy)內(nèi)存分配”算法,它可以高效地將大塊內(nèi)存分割為小塊內(nèi)存。此外,它還可以在最大限度減小內(nèi)存碎片的前提下,高效地分配和釋放不小不同的內(nèi)存塊。

概念

可以定義任意數(shù)量的內(nèi)存池。每個(gè)內(nèi)存池通過其內(nèi)存地址進(jìn)行引用。

內(nèi)存池的關(guān)鍵屬性包括:

  • 塊最小尺寸:以字節(jié)為單位。大于等于 4X 字節(jié),其 0。
  • 塊最大尺寸:以字節(jié)為單位。等于 “塊最小尺寸”*4^Y,其中 Y 大于等于 0。
  • 最大尺寸塊的數(shù)量:大于 0。
  • buffer:內(nèi)存池的塊的實(shí)際內(nèi)存區(qū)域。它必須大于等于 “塊最大尺寸”*“最大尺寸塊的數(shù)量”。

內(nèi)存片的 buffer 必須 N 字節(jié)對(duì)齊,其中 N 是大于 2 的 2 的整數(shù)次冪(例如 4,8,16…)。為了保證 buffer 中的所有內(nèi)存塊都對(duì)齊到這個(gè)邊界,塊的大小必須是 N 的整數(shù)倍。

當(dāng)線程需要內(nèi)存塊時(shí),它只需要從一個(gè)內(nèi)存池中申請(qǐng)。申請(qǐng)成功后,由線程提供的塊描述符的 data 字段表示該內(nèi)存塊的起始地址。當(dāng)線程使用完內(nèi)存塊后,它必須將其釋放給內(nèi)存池,讓其可以重復(fù)利用。

如果沒有找到所期望的內(nèi)存塊,線程可以等待,直到某個(gè)塊可用。多個(gè)線程可以同時(shí)等待某個(gè)空的內(nèi)存池;當(dāng)某個(gè)內(nèi)存塊可用時(shí),它會(huì)被分配給優(yōu)先級(jí)最高的、等待時(shí)間最久的線程使用。

與堆不同的是,如果有需要,可以定義多個(gè)內(nèi)存片。例如不同的應(yīng)用程序可以利用不同的內(nèi)存池。這樣可以阻止某個(gè)應(yīng)用程序“綁架”所有資源。

內(nèi)部操作

內(nèi)存池的 buffer 是一個(gè)數(shù)組,數(shù)組的元素的大小是塊的最大尺寸,這樣能保證塊與塊之間沒有空間被浪費(fèi)。每個(gè)“第 0 級(jí)”的塊是一個(gè) quad-block,(如果有需要)可以被分為四個(gè)小的大小相等的“第 1 級(jí)”塊。類似地,每個(gè)第 1 級(jí)塊也是 quad-block,也可以被分為四個(gè)小的大小相等的“第 2 級(jí)”塊。依次類推。因此,每個(gè)內(nèi)存塊都可以遞歸地分為四分之一的小塊,知道小塊的尺寸不滿足塊最小尺寸。

內(nèi)存池通過一個(gè)叫做 塊集(block set) 的數(shù)據(jù)結(jié)構(gòu)來跟蹤它的 buffer 空間的分區(qū)情況。內(nèi)存池為所支持的每一個(gè)劃分等級(jí)或者每一個(gè)塊尺寸都維持了一個(gè)塊集。每個(gè)塊集使用一個(gè)叫做 quad-block 狀態(tài) 的數(shù)據(jù)結(jié)構(gòu)的數(shù)組來跟蹤它所關(guān)聯(lián)的尺寸的所有空閑塊。

當(dāng)應(yīng)用程序請(qǐng)求一個(gè)內(nèi)存塊時(shí),內(nèi)存池首先會(huì)判斷最小塊的尺寸是否滿足請(qǐng)求,并檢查其相應(yīng)的塊集。如果塊集包含有一個(gè)空閑塊,它會(huì)將該塊標(biāo)記為以使用,然后分配過程就結(jié)束了。如果該塊集不包含空閑塊,內(nèi)存池將嘗試將一個(gè)更大尺寸的空閑塊分類成小的塊,或者將小塊合并為大的塊。如果不能創(chuàng)建這樣的塊,則分配失敗。

內(nèi)存池的塊合并和分裂過程是非常高效的,但是它采用的是遞歸算法,因此很容易產(chǎn)生顯著的開銷。此外,合并算法不能將大小不同的相鄰塊結(jié)合在一起,也不能合并不屬于同一個(gè)父 quad-block 的尺寸相同的相鄰塊。因此,使用內(nèi)存池時(shí)依然會(huì)遇到碎片問題。

當(dāng)應(yīng)用程序釋放一個(gè)已分配的內(nèi)存塊時(shí),僅僅會(huì)在該內(nèi)存塊所關(guān)聯(lián)塊集中將其標(biāo)記為空閑。內(nèi)存池不會(huì)嘗試合并最近釋放的塊,這樣的好處是可以很方便地在其已存在的組織上進(jìn)行重分配。

實(shí)現(xiàn)

定義內(nèi)存池

使用類型為 struct k_mem_pool 的變量可以定義一個(gè)內(nèi)存池。不過,由于內(nèi)存池也需要大量的尺寸可變的數(shù)據(jù)結(jié)構(gòu)來代表它的塊集合和它的 quad-block 的狀態(tài),內(nèi)核不支持在運(yùn)行時(shí)動(dòng)態(tài)地定義內(nèi)存池。內(nèi)存池只能使用 K_MEM_POOL_DEFINE 在編譯時(shí)進(jìn)行定義和初始化。

下面的代碼定義并初始化了一個(gè)內(nèi)存池,這個(gè)內(nèi)存池有三個(gè)大小為 4096 字節(jié)的塊。這些塊也可以被劃分為最小為 64 字節(jié)的 4 字節(jié)對(duì)齊的子塊。(也就是說,內(nèi)存池支持的塊大小是 4096、1024、256 和 64 字節(jié)。)注意,該宏定義了內(nèi)存池的所有數(shù)據(jù)結(jié)構(gòu)和它的 buffer。

K_MEM_POOL_DEFINE(my_pool, 64, 4096, 3, 4);

分配內(nèi)存塊

函數(shù) k_mem_pool_alloc() 用于分配內(nèi)存塊。

下面的代碼會(huì)先等待 100 毫秒,以拿到一個(gè) 200 字節(jié)的可以內(nèi)存塊,然后將其填充為零。如果沒有獲得合適的內(nèi)存塊,代碼會(huì)打印一個(gè)警告信息。

注意,應(yīng)用程序?qū)嶋H會(huì)接收到一個(gè)大小為 256 字節(jié)的內(nèi)存塊,因?yàn)檫@是內(nèi)存池所支持的最接近的尺寸。

struct k_mem_block block;if (k_mem_pool_alloc(&my_pool, &block, 200, 100) == 0)) { memset(block.data, 0, 200);...} else { printf("Memory allocation time-out");}

釋放內(nèi)存塊

函數(shù) k_mem_pool_free() 用于釋放內(nèi)存塊。

下面的代碼基于上面的例程之上,它申請(qǐng)了 75 字節(jié)的內(nèi)存塊,并在不再使用時(shí)釋放。(基于安全考慮,實(shí)際上會(huì)從堆內(nèi)存池使用 256 字節(jié)的內(nèi)存塊。)

struct k_mem_block block;k_mem_pool_alloc(&my_pool, &block, 75, K_FOREVER);... /* use memory block */k_mem_pool_free(&block);

建議的用法

當(dāng)需要分配大小不固定的內(nèi)存時(shí),可以使用內(nèi)存池。

當(dāng)一個(gè)線程需要給另一個(gè)線程發(fā)送大量的數(shù)據(jù)時(shí),可以使用內(nèi)存池,這樣可以避免不必要的數(shù)據(jù)拷貝。

API

頭文件 kernel.h 中提供了如下的內(nèi)存池 API:

  • K_MEM_POOL_DEFINE
  • k_mem_pool_alloc()
  • k_mem_pool_free()
  • http://zephyrproject.cn/zh-cn/docs/latest/k_memory_pool.html

總結(jié)

以上是生活随笔為你收集整理的zephyr 系统--- 内存池使用方法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。