顯示模塊在釋放內(nèi)存時,提示corrupted double-linked
list錯誤。懷疑是內(nèi)存泄露,調(diào)查了一整天,后來發(fā)現(xiàn)某一個通信模塊只要不調(diào)用其下層的某個API就沒有問題。其原因是:該通信模塊把對此API的調(diào)用寫在了回調(diào)函數(shù)當中。 因為回調(diào)函數(shù)屬于下層模塊工作流的一部分,所以要避免在回調(diào)函數(shù)中直接調(diào)用下層的API。 設想一下,上下兩層模塊運行在不同的線程中,下層提供如下3個接口,F(xiàn)unctionA() 和 NotifyOK(),F(xiàn)unctionB(),其中NotifyOK函數(shù)由上層編寫、由下層回調(diào)。工作流程是:當調(diào)用下層的FunctionA之后,要等待下層的回調(diào)通知NotifyOK(),之后再調(diào)用FunctionB()。而在下層的實現(xiàn)中,當FunctionB被調(diào)用時將釋放某段內(nèi)存,這樣的話,如果上層在NotifyOK回調(diào)函數(shù)中調(diào)用FunctionB的話,便會產(chǎn)生這樣的隱患:假如下層在通過NotifyOK通知上層之后使用了這段內(nèi)存,便會出現(xiàn)內(nèi)存泄露(因為其空間已經(jīng)在NotifyOK回調(diào)中被提前釋放了)。 安全的做法是:上層在收到NotifyOK之后,不是立即開始進行之后的工作流(調(diào)用FuntionB),而是以發(fā)消息的方式通知自己進行后續(xù)處理。 至于錯誤發(fā)生的時機,是因為釋放內(nèi)存時,堆管理器才會檢查標記,發(fā)現(xiàn)內(nèi)存泄露。 另外,還搜索了一下相關資料,了解到一些其它的信息。為了提高運算效率,通常分配的內(nèi)存空間要大于申請空間(地址對齊)。當發(fā)生內(nèi)存泄露,使用了申請外的空間,但沒有超出實際分配空間時,有的早期的堆管理器并不會檢查出來(操作系統(tǒng)的內(nèi)存分配實現(xiàn)算法不相同)。 |
|
來自: waitingnothing > 《Nginx》