使用udt庫,編寫簡單的網路通訊程式,發現了乙個問題,關閉一部分連線後,程式占用記憶體並沒有變化。
比如先連線500個,再連線另500個,先關掉後面500個,程式占用記憶體降一半,再關掉500個,程式占用記憶體降到0.1。然而,如果先關掉前面500個,程式占用記憶體不會發生變化,只有等再關掉後面500個,程式記憶體才會降到0.1。
換個順序就降不了,這很奇怪,很「玄學」。
跟蹤**至底層,該有的釋放都有,這是為什麼?靈機一動想到可能與linux記憶體管理機制有關,果不其然,linux中給程式分配堆記憶體後,當程式free,記憶體並不會馬上還給系統,而是交由ptmalloc管轄,這樣程式再需要記憶體的時候,就可以直接向ptmalloc取,不用再向系統申請,效率較高。ptmalloc也不是說就不把記憶體還給系統了,返回記憶體的機制叫「記憶體收縮」,當堆頂的空閒記憶體大於收縮閾值(預設是128kb)時,即可觸發。注意,這邊要求的空閒記憶體必須位於堆頂,所以如果堆頂的記憶體不釋放,堆底的記憶體再怎麼釋放都觸發不了記憶體收縮,這就導致了那個玄學的結果。
因此,在**裡新增這麼一句mallopt(m_mmap_threshold, 128);,m_mmap_threshold是mmap分配閾值,當程式所要記憶體大於m_mmap_threshold時,直接呼叫mmap()分配記憶體,free的時候,會直接呼叫munmap()將記憶體還給作業系統,不再被ptmalloc快取管理。所以連線關閉後,記憶體就能下去了。
這樣做的缺點是需要的記憶體更多,需要的記憶體數量隨m_mmap_threshold數值的減少而增多,所以需要選個合適的數字。且這些記憶體不再重用,分配效率也會比較低。
然而,對於分配長生命週期的大記憶體塊,使用mmap()才是最高效的,ptmalloc並不擅長管理長生命週期的記憶體,尤其是持續不定期分配和釋放長生命週期的記憶體,這會導致記憶體暴增。
解決UDT中記憶體下不去的問題
使用udt庫,編寫簡單的網路通訊程式,發現了乙個問題,關閉一部分連線後,程式占用記憶體並沒有變化。比如先連線500個,再連線另500個,先關掉後面500個,程式占用記憶體降一半,再關掉500個,程式占用記憶體降到0.1。然而,如果先關掉前面500個,程式占用記憶體不會發生變化,只有等再關掉後面500...
iOS中濾鏡處理及相關記憶體洩漏問題的解決
最近工作之餘在做乙個美圖秀秀的仿品 做到濾鏡這塊的時候 自己就參考了網上幾位博主 名字忘了記,非常抱歉 的部落格,但是發現跟著他們的demo做的濾鏡處理,都會有很嚴重的記憶體洩漏,於是就自己按照大體的思路將 重新整理了下,並解決了記憶體洩漏問題。大體思路如下 根據建立乙個coregraphic的圖形...
C 中動態記憶體分配引發問題的解決方案
假設我們要開發乙個string類,它可以方便地處理字串資料。我們可以在類中宣告乙個陣列,考慮到有時候字串極長,我們可以把陣列大小設為200,但一般的情況下又不需要這麼多的空間,這樣是浪費了記憶體。對了,我們可以使用new操作符,這樣是十分靈活的,但在類中就會出現許多意想不到的問題,本文就是針對這一現...