彈性內(nèi)存分配在IOT中的重要性
譯文?譯者 | 張怡
審校 | 孫淑娟
一般而言,開發(fā)人員不太會(huì)考慮內(nèi)存分配。畢竟,現(xiàn)代計(jì)算機(jī)、平板電腦和服務(wù)器的內(nèi)存如此之大,通??雌饋硐袷菬o限的資源。而且,內(nèi)存分配失敗或錯(cuò)誤不太可能發(fā)生,即使出現(xiàn)問題,系統(tǒng)通常默認(rèn)退出程序。
然而,當(dāng)涉及到物聯(lián)網(wǎng)(IoT)時(shí),情況大有不同。在這些嵌入式連接設(shè)備中,內(nèi)存會(huì)變得更加搶手,多個(gè)程序會(huì)爭奪有限的資源;而且集成系統(tǒng)越小,內(nèi)存也更小。因此,最好將其視為有限的資源并保守使用。
正是在這種背景下,內(nèi)存分配(malloc)在IOT行業(yè)中非常重要。malloc是計(jì)算機(jī)在運(yùn)行程序或進(jìn)程時(shí)動(dòng)態(tài)分配內(nèi)存的過程。尤其是對(duì)于連接到互聯(lián)網(wǎng)的設(shè)備,正確處理malloc直接決定其性能好壞。
下面,讓我們來看看開發(fā)人員如何在他們的內(nèi)存分配方法中彈性設(shè)計(jì),以及這對(duì)未來的物聯(lián)網(wǎng)設(shè)備意味著什么。
1、內(nèi)存分配和物聯(lián)網(wǎng)設(shè)備
傳統(tǒng)上,內(nèi)存分配(malloc)經(jīng)常不用于嵌入式系統(tǒng)。這是因?yàn)檩^舊的設(shè)備通常不會(huì)連接到互聯(lián)網(wǎng),因此計(jì)算的內(nèi)存需求并不大。
但是,這些較舊的設(shè)備在系統(tǒng)啟動(dòng)時(shí)創(chuàng)建了一個(gè)資源池來分配資源。一個(gè)資源可以是一個(gè)連接,一個(gè)系統(tǒng)可以配置n個(gè)來自靜態(tài)分配池的連接。
在未連接Internet的系統(tǒng)中,系統(tǒng)的狀態(tài)通常受到一定程度的限制,因此更容易估計(jì)內(nèi)存分配malloc的上限。但是,一旦嵌入式系統(tǒng)連接到互聯(lián)網(wǎng),這種情況就會(huì)發(fā)生巨大變化。
例如,一個(gè)設(shè)備需要計(jì)算多個(gè)連接,并且每個(gè)連接都有不同的內(nèi)存需求,這取決于連接的用途。每個(gè)連接上的數(shù)據(jù)流所需的緩沖內(nèi)存取決于連接的延遲,通過使用某些概率函數(shù)或其他網(wǎng)絡(luò)連接的行為方式來處理數(shù)據(jù)包丟失,從而獲得一定的吞吐量。
通常這在現(xiàn)代高端系統(tǒng)上不是問題。但是,開發(fā)人員在嵌入式環(huán)境中面臨有限的內(nèi)存資源,我們不能簡單地假設(shè)有足夠的內(nèi)存。
這就是為什么在物聯(lián)網(wǎng)嵌入式開發(fā)中,考慮如何規(guī)避內(nèi)存分配錯(cuò)誤或者malloc失敗是非常重要的。
2、現(xiàn)代嵌入式系統(tǒng)和malloc
在現(xiàn)代的嵌入式系統(tǒng)中,malloc的使用頻率更高,許多嵌入式系統(tǒng)和平臺(tái)都有不錯(cuò)的malloc實(shí)現(xiàn)。這種轉(zhuǎn)變的原因是現(xiàn)代連接的嵌入式系統(tǒng)執(zhí)行更多的任務(wù),通常無法靜態(tài)地為所有程序的執(zhí)行分配所需的最大資源。
在現(xiàn)代互聯(lián)嵌入式系統(tǒng)中積極使用malloc,這種轉(zhuǎn)變需要更徹底和系統(tǒng)的軟件測(cè)試來發(fā)現(xiàn)錯(cuò)誤。
通常,malloc錯(cuò)誤不會(huì)系統(tǒng)測(cè)試,因?yàn)樗l(fā)生的概率極低,不值得這么去做。正因?yàn)閙alloc錯(cuò)誤非常罕見,所以其漏洞在發(fā)現(xiàn)之前可能已存在數(shù)年。
3、mallocfail工具:如何測(cè)試錯(cuò)誤
令人高興的是,開發(fā)人員可以利用軟件來測(cè)試分配錯(cuò)誤。有一種新穎的方法是通過運(yùn)行一個(gè)程序,在發(fā)生分配的所有執(zhí)行路徑中注入分配錯(cuò)誤。這可以通過mallocfail工具實(shí)現(xiàn)。
顧名思義,Mallocfail以確定的方式測(cè)試malloc錯(cuò)誤。該工具不是隨機(jī)測(cè)試,而是通過不同的控制路徑自動(dòng)枚舉malloc錯(cuò)誤。它的靈感來自于Stack Overflow。
簡而言之,此工具使用自定義版本分配器malloc、calloc和realloc。每次運(yùn)行自定義分配器時(shí),都會(huì)使用libbacktrace獲取當(dāng)前線程的函數(shù)調(diào)用堆棧,生成對(duì)應(yīng)的 sha256 哈希值。然后,該工具檢查是否出現(xiàn)新的哈希值。如果出現(xiàn)從未見過的哈希(特定的調(diào)用堆棧),則內(nèi)存分配malloc失敗,并將哈希值存儲(chǔ)在內(nèi)存中寫入磁盤;如果之前見過,則正常調(diào)用分配器libc版本。每次程序啟動(dòng)時(shí),已見過的哈希值都會(huì)從磁盤加載。
這是我第一手使用過的東西,發(fā)現(xiàn)非常有用。例如,我們?cè)谇度胧竭吘壾浖_發(fā)工具包上成功測(cè)試了mallocfail。該工具成功識(shí)別了SDK及其第三方庫中的一些問題,而且它們的問題現(xiàn)已修復(fù)了。
4、處理malloc問題
在復(fù)雜的系統(tǒng)中,處理分配錯(cuò)誤可能有點(diǎn)棘手。例如,處理一個(gè)事件需要考慮分配多少內(nèi)存。當(dāng)然,解決方案有很多種。最重要的是分配必要的內(nèi)存,以便在分配失敗時(shí)可以將錯(cuò)誤傳遞回程序,不至于某些問題被悄無聲息的隱藏其中。
處理malloc 失敗的能力是我們團(tuán)隊(duì)經(jīng)常考慮的問題。當(dāng)然,這在其他設(shè)備上可能并沒有什么,但它會(huì)在連接到互聯(lián)網(wǎng)的嵌入式設(shè)備上引起大問題。
因此,我們的 SDK 會(huì)計(jì)算限制某些資源的功能,包括連接、流、緩沖區(qū)等。這樣,系統(tǒng)配置限制使用的內(nèi)存量,以免發(fā)生malloc錯(cuò)誤。
通常,系統(tǒng)內(nèi)存不足會(huì)導(dǎo)致系統(tǒng)難以運(yùn)行。因此,通過限制同時(shí)發(fā)生的功能/任務(wù),降低內(nèi)存分配錯(cuò)誤的概率是很有意義的。
回首過去,我已經(jīng)在這個(gè)互聯(lián)網(wǎng)設(shè)備領(lǐng)域工作了二十年,期待同行開發(fā)人員在現(xiàn)代嵌入式開發(fā)中,采用最佳的malloc實(shí)踐。
建議您深入考慮嵌入式設(shè)備如何解決內(nèi)存分配問題,積極研究使用內(nèi)存的最有效方式。盡可能使用動(dòng)態(tài)內(nèi)存分配和mallocfail測(cè)試進(jìn)行開發(fā),因?yàn)樗鼘?duì)嵌入式物聯(lián)網(wǎng)設(shè)備的性能及其可用性至關(guān)重要。
原文鏈接:https://dzone.com/articles/why-memory-allocation-resilience-matters-in-iot
譯者介紹
張怡,51CTO社區(qū)編輯,主要研究人工智能算法實(shí)現(xiàn)以及場景應(yīng)用,對(duì)機(jī)器學(xué)習(xí)算法和自動(dòng)控制算法有所了解和掌握。?




























