十二:内存简单介绍和OC的内存管理
一、內(nèi)存簡單介紹
內(nèi)存結(jié)構(gòu)
1、運(yùn)行時分配
(1)棧:用戶存放程序臨時創(chuàng)建的局部變量(先進(jìn)后出)。
(2)堆:動態(tài)分配內(nèi)存段。
2、編譯器分配
(1)BSS段:存放未初始化的全局變量和靜態(tài)變量。
(2)數(shù)據(jù)段:已初始化的全局變量和靜態(tài)變量。
(3)代碼段:執(zhí)行代碼的一塊區(qū)域。
地址由低到高:代碼段 -> 數(shù)據(jù)段 -> BSS段-> 堆 -> 棧?
內(nèi)存分配方式
1、從靜態(tài)存儲區(qū)域分配。內(nèi)存在程序編譯的時候就已經(jīng)分配好,這塊內(nèi)存在程序的整個運(yùn)行期間都存在。例如全局變量,static變量。
2、在棧上創(chuàng)建。在執(zhí)行函數(shù)時,函數(shù)內(nèi)局部變量的存儲單元都可以在棧上創(chuàng)建,函數(shù)執(zhí)行結(jié)束時這些存儲單元自動被釋放。棧內(nèi)存分配運(yùn)算內(nèi)置于處理器的指令集中,效率很高,但是分配的內(nèi)存容量有限。
3、從堆上分配,亦稱動態(tài)內(nèi)存分配。動態(tài)內(nèi)存的生存期由程序員決定,使用非常靈活,但如果在堆上分配了空間,就有責(zé)任回收它,否則運(yùn)行的程序會出現(xiàn)內(nèi)存泄漏,頻繁地分配和釋放不同大小的堆空間將會產(chǎn)生堆內(nèi)碎塊。
?
二、OC內(nèi)存管理(iOS7.0后不用手動管理,可以了解相關(guān)原理)
1、進(jìn)行內(nèi)存管理的原因:是由于移動設(shè)備的內(nèi)存極其有限,所以每個APP所占的內(nèi)存也是有限制的,當(dāng)app所占用的內(nèi)存較多時,系統(tǒng)就會發(fā)出內(nèi)存警告,這時需要回收一些不需要再繼續(xù)使用的內(nèi)存空間,比如回收一些不再使用的對象和變量等。
2、內(nèi)存管理范圍:任何繼承NSObject的對象,對其他的基本數(shù)據(jù)類型無效。
本質(zhì)原因是存儲空間不一樣,對象存儲于堆中,而其它局部變量主要存放于棧中,當(dāng)代碼塊結(jié)束時這個代碼塊中涉及的所有局部變量會被回收,指向?qū)ο蟮闹羔樢脖换厥?#xff0c;此時對象已經(jīng)沒有指針指向,但依然存在于內(nèi)存中,造成內(nèi)存泄露。
3、對象的基本結(jié)構(gòu):每個OC對象都有自己的引用計數(shù)器,是一個整數(shù)表示對象被引用的次數(shù),即現(xiàn)在有多少東西在使用這個對象。對象剛被創(chuàng)建時,默認(rèn)計數(shù)器值為1,當(dāng)計數(shù)器的值變?yōu)?時,則對象銷毀。
在每個OC對象內(nèi)部,都專門有4個字節(jié)的存儲空間來存儲引用計數(shù)器。
引用計數(shù)器的作用:判斷對象是否需要回收的唯一依據(jù)就是計數(shù)器是否為0,若不為0則存在。 4、當(dāng)給對象發(fā)送消息時,進(jìn)行引用計數(shù)器操作Retain消息:使引用計數(shù)器+1,改方法返回對象本身
Release消息:使引用計數(shù)器-1(并不代表釋放對象)
retainCount消息:獲得對象當(dāng)前的引用計數(shù)器值
5、當(dāng)一個對象的引用計數(shù)器為0時,那么它將被銷毀,其占用的內(nèi)存被系統(tǒng)回收。當(dāng)對象被銷毀時,系統(tǒng)會自動向?qū)ο蟀l(fā)送一條dealloc消息,一般會重寫dealloc方法,書寫格式如下:
1 - (void)dealloc 2 { 3 [super dealloc] //必須調(diào)用必須調(diào)用調(diào)用此方法,且必須寫在最后 4 }6、注意事項:
野指針錯誤:訪問了一塊壞的內(nèi)存(已經(jīng)被回收的,不可用的內(nèi)存)。
僵尸對象:所占內(nèi)存已經(jīng)被回收的對象,僵尸對象不能再被使用。(打開僵尸對象檢測)
空指針:沒有指向任何東西的指針(存儲的東西是0,null,nil),給空指針發(fā)送消息不會報錯
注意:不能使用[p retaion]讓僵尸對象起死復(fù)生。
7、內(nèi)存管理原則
(1)只要還有人在使用某個對象,那么這個對象就不會被回收。
?只要你想使用這個對象,那么就應(yīng)該讓這個對象的引用計數(shù)器+1。
?當(dāng)你不想使用這個對象時,應(yīng)該讓對象的引用計數(shù)器-1。
(2)誰創(chuàng)建,誰release
?如果你通過alloc,new,copy來創(chuàng)建了一個對象,那么你就必須調(diào)用release或者autorelease方法
?不是你創(chuàng)建的就不用你去負(fù)責(zé)
(3)誰retain,誰release。只要你調(diào)用了retain,無論這個對象時如何生成的,你都要調(diào)用release。
?
三、內(nèi)存管理中的循環(huán)引用問題以及解決
若使用#import的方式相互包含,就會形成了循環(huán)引用。這時可以使用一個@class來代替其中一個#improt來解決循環(huán)引用問題,提高性能!
@class僅僅告訴編譯器,在進(jìn)行編譯的時候把后面的名字作為一個類來處理。
書寫規(guī)范:@class 類名;
作用:聲明一個類,告訴編譯器某個名稱是一個類。
具體用法:1、在.h文件中使用@class來聲明類。
2、在.m文件中真正要使用到的時候,使用#import來包含類中的所有東西。
3、兩端循環(huán)引用的解決方法:一端使用retain,一端使用assign(使用assign的在dealloc中也不用再release)。
轉(zhuǎn)載于:https://www.cnblogs.com/hissia/p/5448410.html
總結(jié)
以上是生活随笔為你收集整理的十二:内存简单介绍和OC的内存管理的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《Redis开发与运维》学习第十章
- 下一篇: 四大主流芯片架构(X86、ARM、RIS