静态、动态内存分配比较
首先,在使用動(dòng)態(tài)分配內(nèi)存技術(shù)前,必須明白自己在做什么,這樣做與其它的方法有什么不同,特別是會(huì)產(chǎn)生哪些負(fù)面影響,天下沒有免費(fèi)的午餐。動(dòng)態(tài)分配內(nèi)存與靜態(tài)分配內(nèi)存的區(qū)別:
1) 靜態(tài)內(nèi)存分配是在編譯時(shí)完成的,不需要占用CPU資源;動(dòng)態(tài)分配內(nèi)存是在運(yùn)行時(shí)完成的,動(dòng)態(tài)內(nèi)存的分配與釋放需要占用CPU資源;
2) 靜態(tài)內(nèi)存分配是在棧上分配的,動(dòng)態(tài)內(nèi)存是堆上分配的;
3) 動(dòng)態(tài)內(nèi)存分配需要指針或引用數(shù)據(jù)類型的支持,而靜態(tài)內(nèi)存分配不需要;
4) 靜態(tài)分配內(nèi)存需要在編譯前確定內(nèi)存塊的大小,而動(dòng)態(tài)分配內(nèi)存不需要編譯前確定內(nèi)存大小,根據(jù)運(yùn)行時(shí)環(huán)境確定需要的內(nèi)存塊大小,按照需要分配內(nèi)存即可。可以這么說,靜態(tài)內(nèi)存分配是按計(jì)劃分配,而動(dòng)態(tài)內(nèi)存分配是按需分配。
5) 靜態(tài)分配內(nèi)存是把內(nèi)存的控制權(quán)交給了編譯器,而動(dòng)態(tài)內(nèi)存是把內(nèi)存的控制權(quán)交給了程序員;
綜上所述,靜態(tài)分配內(nèi)存適合于編譯時(shí)就已經(jīng)可以確定需要占用內(nèi)存多少的情況,而在編譯時(shí)不能確定內(nèi)存需求量時(shí)可使用動(dòng)態(tài)分配內(nèi)存;但靜態(tài)分配內(nèi)存的運(yùn)行效 率要比動(dòng)態(tài)分配內(nèi)存的效率要高,因?yàn)閯?dòng)態(tài)內(nèi)存分配與釋放需要額外的開銷;動(dòng)態(tài)內(nèi)存管理水平嚴(yán)重依賴于程序員的水平,如果處理不當(dāng)容易造成內(nèi)存泄漏。那么再 具體些,如何選擇內(nèi)存分配方式,如果動(dòng)態(tài)分配內(nèi)存需要注意哪些問題呢?
??需要強(qiáng)調(diào)的是,由于動(dòng)態(tài)分配內(nèi)存把內(nèi)存的控制權(quán)交給了程序員,程序員有義務(wù)寫代碼確認(rèn)內(nèi)存分配成功能,如果分配失敗要做適當(dāng)處理,否則將給你的程序進(jìn)而下一個(gè)定時(shí)炸彈,隨時(shí)有可能因?yàn)閯?dòng)態(tài)內(nèi)存分配失敗而導(dǎo)致程序崩潰。
1. 全局變量盡可能不要?jiǎng)討B(tài)分配內(nèi)存。
??既然將變量定義為全局變量,就為了其可見范圍比較寬,因?yàn)榭赡苓@些變量在整個(gè)程序的運(yùn)行期都是可見的,可能根本就沒有機(jī)會(huì)釋放全局變量所占用的內(nèi)存,所以使用動(dòng)態(tài)分配內(nèi)存是意義不大的,只能給程序帶來額外的運(yùn)行負(fù)擔(dān)。
??但對(duì)于全局變量?jī)?nèi)存大小不能確定的情況,可能會(huì)有例外。比如要處理一批數(shù)據(jù),數(shù)據(jù)的大小可能由用戶通過控制臺(tái)參數(shù)形式告訴程序,這種情況可以動(dòng)態(tài)按需分配內(nèi)存,合理使用內(nèi)存。
??而對(duì)于編譯時(shí)能夠確定內(nèi)存使用量的全局變量,而且變量工作期(暫且這么叫吧,就是該變量還可能會(huì)被用到的這段時(shí)期)又與程序的運(yùn)行期相同的情況根本沒有必 要?jiǎng)討B(tài)分配內(nèi)存。這種情況很有意思,就是使用動(dòng)態(tài)分配內(nèi)存,但可以不考慮釋放這塊內(nèi)存,因?yàn)榭梢葬尫艃?nèi)存的時(shí)候該程序也要退出了,程序一結(jié)束,進(jìn)程也就結(jié) 束了,整個(gè)程序所在的虛擬空間已經(jīng)被全部釋放,也就沒必要去添加釋放內(nèi)存的代碼了。(但我確定見到過這樣的代碼)
2. 動(dòng)態(tài)分配內(nèi)存時(shí),分配與釋放的代碼要對(duì)稱。
??這里說的分配與釋放的代碼對(duì)稱指,分配內(nèi)存的代碼要與釋放內(nèi)存的代碼在同一個(gè)范圍的代碼域中,例如在一個(gè)函數(shù)的開頭申請(qǐng)內(nèi)存,就應(yīng)該在這個(gè)函數(shù)的結(jié)尾釋放 內(nèi)存,否則,如果在一個(gè)函數(shù)內(nèi)部分配內(nèi)存,在函數(shù)外釋放內(nèi)存,就有可能因程序員的疏忽造成內(nèi)存泄漏;如果內(nèi)存分配在某個(gè)類的構(gòu)造函數(shù)中,那么就應(yīng)該在析構(gòu) 函數(shù)中釋放內(nèi)存,千不要在另外一個(gè)函數(shù)中釋放,而等著客戶代碼去掉用那個(gè)函數(shù)去手動(dòng)釋放內(nèi)存,如果那樣的話就相當(dāng)于埋了一個(gè)定時(shí)炸彈,隨時(shí)可能因?yàn)橐粫r(shí)的 疏忽而造成內(nèi)存泄漏。
3. 對(duì)動(dòng)態(tài)創(chuàng)建的對(duì)象或分配的內(nèi)存塊一定要檢查期有效性。
??由于操作系統(tǒng)的并發(fā)性和復(fù)雜性,任何一次動(dòng)態(tài)內(nèi)存的分配操作都有可能失敗,特別是申請(qǐng)一次較大塊內(nèi)存時(shí)。所以一定要檢查動(dòng)態(tài)創(chuàng)建的對(duì)象或申請(qǐng)的堆內(nèi)存是否 成功,否則可能因?yàn)殄e(cuò)誤的指針或空指針造成程序異常,如果異常沒有得到適當(dāng)處理的話,可能使整個(gè)程序意外終止,造成損失。
4. 盡可能少次數(shù)地使用動(dòng)態(tài)內(nèi)存分配。
??動(dòng)態(tài)分配是在運(yùn)行時(shí)由操作系統(tǒng)完成的,所以是要消耗CPU資源的,在進(jìn)行動(dòng)態(tài)內(nèi)存分配時(shí)盡可能便利已經(jīng)分配的資源。如果上次申請(qǐng)的資源夠用就不要重新申請(qǐng)資源,不夠用時(shí)才釋放舊資源,申請(qǐng)新資源。
5. 在保證資源利用率的前提下,能用靜態(tài)內(nèi)存分配不用動(dòng)態(tài)分配,特別是局部臨時(shí)對(duì)象。
??例如,對(duì)于局部對(duì)象,使用靜態(tài)分配的內(nèi)存,可以由編譯器編譯時(shí)分配,超出作用域自動(dòng)內(nèi)存,不僅減小了程序代碼,減少了錯(cuò)誤產(chǎn)生的概率,減輕了程序員的負(fù)擔(dān),而且提高的程序的執(zhí)行效率,何樂而不為呢?
總結(jié)
以上是生活随笔為你收集整理的静态、动态内存分配比较的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 实时操作系统主流调度方法RMS
- 下一篇: 几种嵌入式RTOS的分析与比较