OC 記憶體洩露 自動釋放池

2022-03-29 20:05:08 字數 950 閱讀 2466

花絮:看到下面的**就想起這麼乙個調侃:

乙個老程式設計師,功成名就,金盆洗手不在寫**後,決定練練書法。提筆思索良久後在紙上寫下:hello world!

1 首先說下自動釋放池的底層實現

它是通過以 autoreleasepoolpage 為結點的雙向鍊錶來實現的。很類似棧的方式:對應push操作(底層是標記乙個哨兵),這時相當於建立了乙個自動釋放池。當乙個物件收到傳送autorelease訊息時,它被新增剛建立的自動釋放池中,當自動釋放池被**時(對應pop操作),哨兵之後新增進來的物件從池中被刪除, 並且會給它們傳送release訊息。則物件引用計數-1,如果為0則釋放記憶體。很明顯arc相對於mrc,物件會延遲釋放。

2 舉例

有這麼一段**:largenumber可以當做乙個很大的數

for (int i = 0 ; i < largenumber; i++)

那麼會有什麼問題呢?

如果largenumber不大時沒有問題,但是當它很大時問題非常嚴重!造成記憶體峰值。雖然arc會自動釋放記憶體,但是只有pop操作(完成一次runloop訊息迴圈或@autoreleasepool {}結尾時)才會給池子裡面的所有物件做一次release操作。

當我們使用for迴圈建立很多個使用autorelease方式建立的nsstring物件的時候,將所有的物件的釋放權都交給了這個釋放池,而這個釋放池會等待完整的迴圈之後才有可能釋放,因此就會使物件無法及時釋放,堆積在記憶體造成記憶體峰值。

**應該這樣修改:在迴圈內新增乙個自動釋放池,此時自動釋放池就會處於當前執行緒的棧頂,那麼每執行一次迴圈,就會新建乙個自動釋放池(push),迴圈結束進行一次(pop操作),那麼新增在池子裡面的物件就會被釋放,則不會造成記憶體峰值。

for (int i = 0 ; i < largenumber; i++) 

}

OC自動記憶體釋放總結

autorelease方法不會改變物件的引用計數器,只是將這個物件放到自動釋放池中 自動釋放池實質是當自動釋放池銷毀後呼叫物件的release方法,不一定就能銷毀物件 例如如果乙個物件的引用計數器 1則此時就無法銷毀 由於自動釋放池最後統一銷毀物件,因此如果乙個操作比較占用記憶體 物件比較多或者物件...

自動釋放池

自動釋放池是什麼時候建立的?又是什麼時候銷毀的?原題 思考 1,有返回值的類方法建立出來的物件都是autorelease的。autorelease物件出了作用域後,就會被新增到自動釋放池中。如果largenumber非常大,有可能在乙個for中就把自動釋放池填滿,記憶體消耗非常大!2,解決方案 在f...

自動釋放池

autorelease本質上就是延遲呼叫release方法 autorelease物件什麼時候釋放?引用計數為0的時候才會釋放,不是出了pool就釋放 在一些很消耗記憶體的迴圈呼叫的場景下有時需要手動干預autoreleased物件的釋放時機,不然會導致記憶體暴增,最終導致程式崩潰 nsthread...