簡(jiǎn)析iOS內(nèi)存管理

關(guān)于內(nèi)存,首先講要介紹兩個(gè)概念虛擬內(nèi)存, 物理內(nèi)存。
物理內(nèi)存:這個(gè)就沒啥好說的了,就是實(shí)際上你的硬件內(nèi)存是多少那就是多少。
虛擬內(nèi)存:這個(gè)是一種對(duì)于物理內(nèi)存的使用優(yōu)化方案。先假設(shè)有很大的空間可以使用,實(shí)際上是有條理的把要使用到的東西放到物理內(nèi)存中去。
打個(gè)比方:你向家里的領(lǐng)導(dǎo)申請(qǐng)了1000塊的零花錢,領(lǐng)導(dǎo)也批準(zhǔn)了,但是并不會(huì)一開始就給你1000塊。只會(huì)在你真的要出去喝朋友聚餐的時(shí)候,需要多少錢就給你多少錢。多的一毛也沒有。

進(jìn)入正題
我們?nèi)粘I梢粋€(gè)對(duì)象都會(huì)

image.png

習(xí)慣性的alloc,init一氣呵成。仿佛絕世高手一般絲毫不拖泥帶水。
那么有沒有想過alloc,init還有一個(gè)沒什么人用的new,他們到底是做了些什么呢!

alloc的操作實(shí)際上就像是向內(nèi)存進(jìn)行申請(qǐng)一塊內(nèi)存

image.png

當(dāng)執(zhí)行alloc操作后,內(nèi)存就會(huì)分配一塊內(nèi)存給對(duì)象并返回指針。

image.png

但是對(duì)于這樣的對(duì)象,你只能做一些簡(jiǎn)單的操作

image.png
image.png

假設(shè)有這樣一個(gè)函數(shù),并在分配好內(nèi)存后去調(diào)用

image.png

結(jié)果還是可以調(diào)用到的,但是如果包含一些對(duì)象的操作

image.png

最后只能是無能為力了

image.png

原因就在于并沒有調(diào)用到init這個(gè)方法,對(duì)相應(yīng)的對(duì)象進(jìn)行初始化。
所以alloc是進(jìn)行內(nèi)存的申請(qǐng),init是做初始化的操作。

那么new呢?
實(shí)際上new的功能是等同于 [[ alloc] init]的,但是在很多的情況下,我們要用到的是 [[ alloc] initWith......]這樣的形式來進(jìn)行初始化對(duì)象。new的應(yīng)用場(chǎng)景就顯得太過局限了

image.png
image.png
image.png

講完基本alloc,init,new的區(qū)別,那么再來想一個(gè)問題,alloc申請(qǐng)的到底是虛擬內(nèi)存還是物理內(nèi)存呢
我們可以通過instruments來進(jìn)行查看
我們先建立這樣一個(gè)函數(shù)

image.png

通過按鈕來進(jìn)行控制,每次點(diǎn)擊按鈕就循環(huán)生成100000個(gè)對(duì)象,然后看看instruments里面有關(guān)內(nèi)存的Persistent Bytes的數(shù)據(jù)
第一次點(diǎn)擊

image.png

第二次點(diǎn)擊

image.png

第三次點(diǎn)擊

image.png

可以看到,每次點(diǎn)擊都穩(wěn)定的添加1.53M左右的實(shí)際內(nèi)存,最后證明,alloc所申請(qǐng)的是物理內(nèi)存!

那么,問題又來了,為什么每次建立100000個(gè)MemoryModel會(huì)占用是1.53M呢,不是1M也不是10M呢
我們先看下Model里面的對(duì)象組成

image.png

只有一個(gè)NSString的對(duì)象,我們知道在64位操作系統(tǒng)里面,NSString應(yīng)該是8字節(jié)的,那么我們生成一個(gè)MemoryModel對(duì)象看看占用多少的內(nèi)存

image.png

什么鬼,為什么最后輸出的是16個(gè)字節(jié)?難道是編譯器抽風(fēng)了?我們?cè)倏纯慈绻莾蓚€(gè)NSString的對(duì)象呢

image.png
image.png

居然是32?難道是記錯(cuò)了,NSString就是16字節(jié)的么?
再加一個(gè)int類型的試試

image.png
image.png

怎么又是32,這回徹底懵逼了。

產(chǎn)生這種詭異的現(xiàn)象的原因是因?yàn)樘O果在內(nèi)存分配上是遵循的字節(jié)對(duì)齊原則的!
當(dāng)我們分配一塊內(nèi)存的時(shí)候,假設(shè)需要的內(nèi)存小于16個(gè)字節(jié),操作系統(tǒng)會(huì)直接分配16個(gè)字節(jié);加入需要的內(nèi)存大于16個(gè)字節(jié),操作系統(tǒng)會(huì)分配a*16個(gè)字節(jié)。
現(xiàn)在我們來算一下前面三個(gè)例子為什么會(huì)輸出16,32,32

每個(gè)對(duì)象的isa會(huì)占用8字節(jié),NSString對(duì)象也會(huì)占用8字節(jié),int類型占用4字節(jié)
1:8 + 8 = 16 這個(gè)結(jié)果正好就是輸出的16
2:8 + 8 + 8 = 24 , 16 < 24 < 32 根據(jù)字節(jié)對(duì)齊規(guī)則,最后輸出的是32
3:8 + 8 + 8 + 4 = 28, 16 < 28 < 32 根據(jù)字節(jié)對(duì)齊規(guī)則,最后輸出32

知道了這個(gè)規(guī)則,那么就能明白你所生成的對(duì)象到底會(huì)占用多少的內(nèi)存了。

以上內(nèi)容,如有虛構(gòu),請(qǐng)及時(shí)指出,就是這樣,喵

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容