總結之 記憶體管理

2021-07-05 04:32:23 字數 3271 閱讀 3200

一、記憶體管理的原因

本質原因:因為物件和其他資料型別在系統中的儲存空間不一樣,其它區域性變數主要存放於棧中,而物件儲存於堆中,當**塊結束時這個**塊中涉及的所有區域性變數會被**,指向物件的指標也被**,此時物件已經沒有指標指向,但依然存在於記憶體中,造成記憶體洩露。

二、記憶體管理

所謂記憶體管理,就是對記憶體進行管理,涉及的操作有:a、分配記憶體 :比如建立乙個物件, 會增加記憶體占用。  b、清除記憶體 :比如銷毀乙個物件, 能減小記憶體占用。

記憶體管理的管理範圍: a、任何繼承了nsobject的物件。b、對其他非物件型別無效如int,char,float,double,struct,enum等

三、引用計數器

每個oc物件內部都有4個位元組的儲存空間來存放引用計數器。

1、引用計數器的作用:簡單來說,可以理解為:引用計數器表示有多少人正在使用這個物件。

a、當物件的引用計數器為0時,  物件占用的記憶體就會被系統**。如果物件的計數器不為0,那麼在整個程式執行過程,它占用的記憶體就不可能被**(除非整個程式已經退出 )

b、任何乙個物件,剛生下來的時候,引用計數器都為1。當使用alloc、new或者copy建立乙個物件時,物件的引用計數器預設就是1。

2、引用計數器的常見操作

a、給物件傳送一條retain訊息, 可以使引用計數器值+1(retain方法返回物件本身)

b、給物件傳送一條release訊息, 可以使引用計數器值-1

c、給物件傳送retaincount訊息, 可以獲得當前的引用計數器值

注意: release並不代表銷毀\**物件, 僅僅是計數器-1

四、物件的銷毀(dealloc)

1、當乙個物件的引用計數器值為0時,這個物件即將被銷毀,其占用的記憶體被系統**,系統會自動給物件傳送一條dealloc訊息。(因此, 從dealloc方法有沒有被呼叫,就可以判斷出物件是否被銷毀)

2、dealloc方法的重寫

a、一般會重寫dealloc方法, 在這裡釋放相關資源,dealloc就是物件的遺言。

b、一旦重寫了dealloc方法, 就必須呼叫[superdealloc],並且放在最後面呼叫。

3、使用注意:a、不能直接呼叫dealloc方法。b、一旦物件被**了,它占用的記憶體就不再可用,堅持使用會導致程式崩潰(野指標錯誤)

4、野指標/空指標

a、殭屍物件:已經被銷毀的物件,即所佔記憶體已經被**的物件。

b、野指標:指向殭屍物件(不可用記憶體)的指標。給野指標發訊息會報exc_bad_access錯誤。

c、空指標:沒有指向儲存空間的指標,即裡面存的是nil,也就是。

為了避免野指標錯誤的常見辦法:在物件被銷毀之後,將指向物件的指標變為空指標。

五、記憶體管理原則

蘋果官方規定的記憶體管理原則:

1、誰建立誰release : 如果你通過alloc、new或[mutable]copy來建立乙個物件,那麼你必須呼叫release或autorelease。

2、誰retain誰release :只要你呼叫了retain,就必須呼叫一次release。

簡單來說:有加就有減。曾經讓物件的計數器+1,就必須在最後讓物件計數器-1。

3、多物件的記憶體管理

如果對多個物件進行記憶體管理,並且物件之間是有聯絡的,比如,某乙個物件中又包含另乙個物件的屬性, 那麼管理就會變得比較複雜。

管理規律:a、只要還有人在用某個物件,那麼這個物件就不會被**。2、只要你想用這個物件,就讓物件的計數器+1。3、當你不再使用這個物件時,就讓物件的計數器-1。

六、@property引數

1、記憶體管理相關引數

retain:對物件release舊值,retain新值(適用於oc物件型別)

assign:直接賦值(預設,適用於非oc物件型別)

copy:release舊值,copy新值(一般用於nsstring * )

2、控制是否要生成set方法

readonly:唯讀,只會生成getter的宣告和實現

readwrite:預設的,同時生成setter和getter的宣告和實現

3、多執行緒管理

蘋果在一定程度上遮蔽了多執行緒操作

nonatomic:高效能,一般使用這個

atomic:低效能 

七、autorelease(緩衝池)

1、基本用法

a、會將物件放到乙個自動釋放池中。

b、當自動釋放池被銷毀時,會對池子裡的所有物件做一次release。

c、會返回物件本身。

d、呼叫完autorelease方法後,物件的計數器不受影響(銷毀時影響)。

2、好處:a、不需要再關心物件釋放的時間。b、不需要再關心什麼時候呼叫release。

使用注意:a、占用記憶體較大的物件,不要隨便使用autorelease,應該使用release來精確控制。b、占用記憶體較小的物件使用autorelease,沒有太大的影響。

3、autorelease注意

a、系統自帶的方法中,如果不包含alloc new copy等,則這些方法返回的物件都是autorelease的,如[nsdate  date];

b、開發中經常會寫一些類方法來快速建立乙個autorelease物件,建立物件時不要直接使用類名,而是使用self。

八、arc記憶體管理機制

1、arc的判斷準則:只要沒有強指標指向物件,物件就會被釋放。

2、指標分類:a、強指標:預設的情況下,所有的指標都是強指標,關鍵字strong。b、弱指標:_ _weak關鍵字修飾的指標

宣告乙個弱指標如下:_ _weak person *p;

arc中,只要弱指標指向的物件不在了,就直接把弱指標做清空操作。

arc中在property處不再使用retain,而是使用strong,在dealloc中不需要再[super dealloc]。

@property(nonatomic,strong)dog *dog;// 意味著生成的成員變數_dog是乙個強指標,相當於以前的retain。

如果換成是弱指標,則換成weak,不需要加_ _。

3、arc的特點總結:a、不允許呼叫release,retain,retaincount。b、不允許重寫dealloc,但是不允許呼叫[super dealloc]。          @property的引數:

strong:相當於原來的retain(適用於oc物件型別),成員變數是強指標。

weak:相當於原來的assign,(適用於oc物件型別),成員變數是弱指標。

assign:適用於非oc物件型別(基礎型別)。

記憶體管理之記憶體定址

記憶體定址 三種記憶體位址 邏輯位址 logical address 包含機器語言指令中用來指定乙個運算元或一條指令的位址 線性位址 linear address 線性位址也稱為虛擬位址 virtual address 實體地址 physical address 用於記憶體晶元級記憶體單元定址,他們...

c 之記憶體管理

c 使用3 種不同解決方案儲存資料,區別是資料保留在記憶體中的時間 兩種儲存持續性為自動 自動變數和暫存器變數 register 沒有記憶體位址 堆疊 在函式外定義的變數和使用關鍵字static定義的變數的儲存持續性都為靜態.分為 3 外部鏈結性,內部鏈結性和無鏈結性 所有靜態變數都有下面的兩個初始...

LiteOS之記憶體管理

liteos的記憶體支援靜態分配 動態分配兩種,亦即box和dlink演算法,類似位元組塊和位元組池的差異,靜態分配方式中儲存空間大小一致,而動態分配可以使用變化大小的儲存空間。一 box分配方式 box演算法中記憶體塊的大小是由初始化的時刻固定的。提供magic賦值方式用於記憶體檢查,即在每塊申請...