記憶體管理詳解

2021-07-24 14:43:17 字數 3548 閱讀 3761

來談談記憶體管理

首先知道記憶體管理是什麼

應用程式記憶體管理是在程式執行的時候合理的分配記憶體(分配記憶體時不會造成記憶體洩露等)與清除記憶體(銷毀乙個不用的程式,減少記憶體使用)

在oc中有兩個管理記憶體的模式

mrr(manual retain-release),也被人稱作mrc(manual reference counting,手動引用計數)

arc(automatic reference counting,自動引用計數)

如何調整

在build setting中的objective-c automatic reference counting設定為yes即為arc

注意點,所有繼承nsobject的物件都需要管理記憶體,因為存放在堆裡面,基本資料型別不需要管理記憶體,因為放在棧裡面

堆: 一般由程式設計師分配釋放記憶體,若程式設計師不釋放,程式結束時可能由os釋放,其操作方式類似於資料結構中的鍊錶

棧: 由作業系統自動分配釋放,存放函式的引數值,區域性變數值等,其操作方式類似於資料結構中的棧(先進後出)

在ios5以前,程式都需要手動新增retain,release,atorelease來管理物件的記憶體

當使用alloc、new、copy、mutablecopy建立乙個新物件時,該新物件的引用計數器為1

當給物件傳送一條retain訊息時,物件的引用計數器+1(方法返回物件本身)

當給物件傳送一條release訊息時物件的引用計數器-1(方法無返回值)

當給物件傳送一條retaincount訊息時,返回物件的當前引用計數器(不要以該資料來判斷物件是否被釋放)

注意點:

對物件傳送乙個release訊息,不代表物件會釋放,只有物件的引用計數器為0時才會被釋放

在記憶體管理中,會產生將是物件,野指標,空指標

殭屍物件: 所占用的記憶體已經被**的物件,殭屍物件不能再使用

野指標: 指向殭屍物件的指標,給野指標傳送訊息會報錯exc_bad_access錯誤:訪問了一塊已經被**的記憶體

空指標: 沒有指向任何物件的指標(儲存的東西是nil,null,0),給空指標傳送訊息不會報錯,系統什麼也不會做,所以在物件被釋放時將指標設定為nil可以避免野指標錯誤

殭屍物件,xcode是不會主動監聽的,需要我們自己去開啟

步驟很簡單,

物件步驟為: edit scheme ->; run ->; diagnostics ->; objective-c的enable zombie objects打鉤

dog *d = [[dog alloc] init]; // 引用計數器 = 1

[d release]; // 引用計數器 - 1 = 0,指標所指向的物件的記憶體被釋放

[p release]; // 這句給野指標傳送訊息,會報野指標錯誤,開啟監聽殭屍物件會給出錯誤資訊**- -[person release]: message sent to deallocated instance 0x100206fd0

自動釋放池的概括

自動釋放池提供了延遲放棄乙個物件的所有權的機制,比如想要在乙個方法中返回乙個物件,如果先使用release放棄了該物件的所有權,那麼return返回的物件便是乙個殭屍物件,如果先進行return返回,那麼便無法放棄該物件的所有權,導致了記憶體洩漏

autorelease是一種支援引用計數的記憶體管理方式,只要在自動釋放池中給物件傳送一條autorelease訊息,就會將物件放到自動釋放池中,當自動釋放池被銷毀時,會對池中的所有物件傳送一條release訊息

autorelease方法會返回物件本身

autorelease方法不會修改物件的引用計數器

autorelease方法可以讓開發者不用實時關心什麼時候傳送release訊息

類工廠方法記憶體管理

在開發中,我們經常使用foundation框架中的類,在呼叫其類工廠方法建立乙個物件時,因為並不是使用alloc,new,copy或者mutablecopy方法建立的,所以並不需要我們自己在給該物件傳送release或者autorelease訊息,這是因為類工廠方法內部都已經在返回物件前進行過延遲釋放

我們在自己書寫類工廠方法時,也應該與系統處理方式相同,快速返回乙個autorelease物件的方式具體如下

+ (instancetype)person

快速返回乙個帶有引數的autorelease物件的方式具體如下

+ (instancetype)personwithname:(nsstring *)name

arc的概括

arc是ios4引入的一項新技術(從ios5開始支援弱引用),其使用與mrr&mrc相同的記憶體管理規則來管理記憶體,不過編譯器會在編譯階段自動的插入retain、release和autorelease等記憶體管理**來管理記憶體不再需要程式人員手動管理.非常方便,所以現在用的都是arc模式

多人開發時需要注意的

1> 使用analyze進行**的靜態分析

2> 為避免不必要的麻煩, 多人開發時盡量使用arc

和mrc相比消除了手動管理記憶體的煩惱,不需要手動呼叫retain,release和aytorelease等方法來管理記憶體

編譯器還會在適當的位置上插入**

在arc和mrc的屬性修飾符

strong用於oc物件,相當於mrc中的retain

weak用於oc物件,相當於mrc中的assign

assign用於基本資料型別,相當於mrc中的assign

在什麼情況下會發生記憶體洩露

1> 當程式在申請記憶體後,無法釋放已申請的記憶體空間(例如乙個物件或者變 量使用完成後沒有釋放,這個物件一直占用著記憶體),一次記憶體洩露危害 可以忽略,但記憶體洩露堆積後果很嚴重,無論多少記憶體,遲早會被占光。

2> 記憶體洩露會最終會導致記憶體溢位! 當程式在申請記憶體時,沒有足夠的記憶體空間供其使用,出現out of memory;比如申請了乙個int,但給它存了long才能存下的數,那就是記憶體溢位。

ios記憶體管理之copy

概述 copy(複製、拷貝)是產生乙個副本物件的過程,只要是通過拷貝產生的副本物件,副本物件中的內容與源物件中的內容就完全一致,下面介紹幾個copy相關的知識點

copy的特點

修改源物件的屬性和行為,不會影響副本物件

修改副本物件的屬性和行為,不會影響源物件

copy與mutablecopy

使用copy產生的副本物件是不可變的(如nsstring,nsarray)

使用mutablecopy產生的副本物件是可變的(如nsmutablestring,nsmutablearray)

通過拷貝是否會產生新的物件

通過拷貝是否會產生新物件,就要看源物件與副本物件是否滿足拷貝的特點

可變物件通過mutablecopy,會生成新的物件

可變物件通過copy,會生成新的物件

不可變物件通過mutablecopy,會生成新的物件

不可變物件通過copy,不會生成新的物件(因為源物件與副本物件都是不可變的,已經滿足拷貝的特點)

深拷貝(內容拷貝)與淺拷貝(指標拷貝)

深拷貝: 如果通過拷貝生成了新物件,就稱為深拷貝(內容拷貝)

淺拷貝: 如果通過拷貝沒生成新物件,就稱為淺拷貝(指標拷貝)

C 記憶體管理詳解

偉大的bill gates 曾經失言 640k ought to be enough for everybody bill gates 1981 程式設計師們經常編寫記憶體管理程式,往往提心吊膽。如果不想觸雷,唯一的解決辦法就是發現所有潛伏的地雷並且排除它們,躲是躲不了的。本文的內容比一般教科書的要...

C 記憶體管理詳解

踏入c 中的雷區 c 記憶體管理詳解 這篇文章回答了我之前的乙個問題,就是分配記憶體用malloc好,還是用new好,今天跑程式的時候,發現malloc老是失敗,氣得不行,最後看到了這篇文章,原來如此,以後堅決用new了。1 有了malloc free為什麼還要new delete?malloc與f...

iOS 記憶體管理詳解

在arc下主要有以下幾個關鍵字 1.關鍵字 strong 預設值,表示只要有強引用指標指向該變數,則該變數會一直存在。2.關鍵字 weak 弱引用,表示若沒有任何強引用指標指向該變數,會自動將變數的值置為空,即nil狀態。3.關鍵字 autoreleasing 用於標示自動釋放的變數 4.關鍵字 u...