您好,登錄后才能下訂單哦!
這期內容當中小編將會給大家帶來有關如何實現IAR中使用堆和棧的問題分析,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
堆是什么?
堆是內存空間里為動態內存分配保留的一部分區域
當一個應用需要臨時使用一定數量的內存時可以從堆空間分配或借用,C中通過調用malloc()函數實現,C++中通過’new’來實現
當這個內存不再需要時可以通過調用free()函數或者使用delet操作符來釋放。一旦該內存被釋放,可以再次分配使用。
堆的位置和大小是在編譯時靜態設置的。
為你的應用分配合適的堆空間很重要,否則在運行時可能崩潰。
怎樣決定堆大小
考慮應用使用的動態內存時的首要問題是我需要多少堆空間?
相比來說這更像是估計而不是計算
如果你知道你的應用怎樣行動,那么你應該大概知道每個時刻應該分配多少內存
另外需要考慮在管理堆空間是有一些額外的開銷
堆管理器需要跟蹤已經使用的和剩余的空間數量,已經分配了的塊大小,通常還包含一個指向下一個可用內存的指針
另外,開發工具可能為了維護內存體系結構保留一定的內存塊。譬如,EWARM編譯器通常為保證棧對齊而保留8字節倍數的內存塊。
潛在的問題
當不同規模的內存塊頻繁分配、釋放時,動態內存分配是最常發生的問題隨之而來。
當內存釋放時,就會有一個空位
如果下一個要分配的空間比所有的空位都要大,這就會是個問題
這為debugging帶來困難,因為堆上總的空閑內存空間比要分配的要大,但是內存申請可鞥因為空閑空間不連續而失敗。
例如,假設如下:
堆的位置為0x20000-0x20FFF
一個8字節的內存塊分布在該區間的開始位置
緊接著是一個1024字節的塊
之后,第一個塊被釋放并可以再次使用。然而,應用需要分配大于8字節的空間,所以開始 的8字節空間就無法使用。這就是內存碎片化,如果應用用于不在需要8字節或更少的內存空間,那么這8字節的內存空間就浪費了。這個例子也說明了為什么堆中的小內存塊是低效的,這種開銷等于應用可用數據的數量。
堆的布局
有些情況下確切的知道堆上有些什么,位于什么位置是非常有用的。
堆上包含的不只是分派的數據:
有一些維護堆的額外開銷
每一個分配的內存塊都包含兩個整數,指針的大小取決于CPU的架構,e.g. ARM器件會使用32bit的整數。
第一個整數指明分派的內存塊的大小。
最后一個堆對象后會有一個32bit的值來說明剩余的堆空間。
最后一個堆對象開始位置的32bit值說明這個數據的地址。
堆同時跟蹤下一個分配的位置,使用一個駐留在堆外部的結構體中。
typedef struct {
__data_Cell __data * __data *_Plast;
__data_Cell __data *_Head; }
__data_Altab;
指針_Head說明堆的當前狀態。指針_Plast說明從哪里開始搜索目前未使用的可用塊。
__data_Cell結構體定義如下:
typedef struct __data_Cell
{
__data_size_t _Size;
struct __data_Cell __data *_Next;
} __data_Cell;
其中_Size 說明堆的剩余數量, _Next 說明下一個可用分配的內存地址。如果堆空間耗盡,_Next指針則為NULL。
堆的最終思考
如果沒有一些工具輔助你分析動態內存需求,直接估計堆空間是比較困難的。
在桌面Java中有這樣的工具(HAT,Heap Analysis Tool)
嵌入式C/C++中還沒有類似工具
針對資源有限的嵌入式系統,由于額外的開銷和可能的堆內存碎片化,動態內存應該盡量少用。
在你的代碼中(測試用例中)你可以創建多個結構體或者對象
MISRA C要求所有內存都必須在編譯時靜態分配,因此你永遠也不會跑出堆空間。
EWARM中的堆統計
EWARM中的C-Spy debugger讓你可以看到當前堆的使用情況
要看到這個功能,必須在工程中包含 dlmalloc.c
調用 __iar_dlmallinfo() 和 __iar_dlmalloc_stats() 會在Terminal I/O窗口打印堆統計情況。
4.如果給定太大的棧空間,RAM就浪費了,如果給定的棧空間太小,會出現兩種情況(取決于棧在內存空間的位置):
a 變量會被改寫,導致未定義的行為
b 棧會超出內存空間,導致應用的異常終止
因為第二種選擇比較用于檢測到,你應該考慮將棧設置為朝內存重點增長。
靜態棧檢查器
有很多靜態的C語言檢查器
Express Logic’s StackX
Abslnt’s StackAnalyzer
John Regher’s Stack Analysis(for AVR/430 only)
AdaCore’s GNATStack
Embedded Workbench’s Stack Plug-in
EW包含一個易用的棧插件,可以監控CSTACK的大小,同時如果你超出指定的棧門限將輸出消息到debug日志。
警告:該插件對于RTOS是無效的,使用RTOS時他始終匯報堆棧溢出。
上述就是小編為大家分享的如何實現IAR中使用堆和棧的問題分析了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。