1.內(nèi)存區(qū)域
1>堆和棧的區(qū)別
管理方式:對(duì)于棧來講,是由編譯器自動(dòng)管理,無需我們手工控制;對(duì)于堆來說,釋放工作由程序員控制,容易產(chǎn)生memory leak。
申請(qǐng)大小:
棧:在Windows下,棧是向低地址擴(kuò)展的數(shù)據(jù)結(jié)構(gòu),是一塊連續(xù)的內(nèi)存的區(qū)域。這句話的意思是棧頂?shù)牡刂泛蜅5淖畲笕萘渴窍到y(tǒng)預(yù)先規(guī)定好的,在 WINDOWS下,棧的大小是2M(也有的說是1M,總之是一個(gè)編譯時(shí)就確定的常數(shù)),如果申請(qǐng)的空間超過棧的剩余空間時(shí),將提示overflow。因此,能從棧獲得的空間較小。
堆:堆是向高地址擴(kuò)展的數(shù)據(jù)結(jié)構(gòu),是不連續(xù)的內(nèi)存區(qū)域。這是由于系統(tǒng)是用鏈表來存儲(chǔ)的空閑內(nèi)存地址的,自然是不連續(xù)的,而鏈表的遍歷方向是由低地址向高地址。堆的大小受限于計(jì)算機(jī)系統(tǒng)中有效的虛擬內(nèi)存。由此可見,堆獲得的空間比較靈活,也比較大。
碎片問題:
對(duì)于堆來講,頻繁的new/delete勢(shì)必會(huì)造成內(nèi)存空間的不連續(xù),從而造成大量的碎片,使程序效率降低。對(duì)于棧來講,則不會(huì)存在這個(gè)問題,因?yàn)闂J窍冗M(jìn)后出的隊(duì)列,他們是如此的一一對(duì)應(yīng),以至于永遠(yuǎn)都不可能有一個(gè)內(nèi)存塊從棧中間彈出
分配方式:
堆都是動(dòng)態(tài)分配的,沒有靜態(tài)分配的堆。棧有2種分配方式:靜態(tài)分配和動(dòng)態(tài)分配。靜態(tài)分配是編譯器完成的,比如局部變量的分配。動(dòng)態(tài)分配由alloca函數(shù)進(jìn)行分配,但是棧的動(dòng)態(tài)分配和堆是不同的,他的動(dòng)態(tài)分配是由編譯器進(jìn)行釋放,無需我們手工實(shí)現(xiàn)。
分配效率:
棧是機(jī)器系統(tǒng)提供的數(shù)據(jù)結(jié)構(gòu),計(jì)算機(jī)會(huì)在底層對(duì)棧提供支持:分配專門的寄存器存放棧的地址,壓棧出棧都有專門的指令執(zhí)行,這就決定了棧的效率比較高。堆則是C/C++函數(shù)庫提供的,它的機(jī)制是很復(fù)雜的。
2.iOS內(nèi)存管理
1> 字符串的內(nèi)存管理
創(chuàng)建字符串的內(nèi)存空間??堆? 常量區(qū)
2> 循環(huán)引用
delegate屬性的內(nèi)存策略
block循環(huán)引用???實(shí)際場(chǎng)景
3> autorelease的使用?? 工廠方法為什么不釋放對(duì)象??ARC下autorelease的使用場(chǎng)景
避免內(nèi)存峰值
SDWebimage中加載gif圖片??大循環(huán)
棧結(jié)構(gòu) 棧頂
統(tǒng)一發(fā)release消息
4> ARC和MRC的混用
4.1> MRC>ARC
把MRC的代碼轉(zhuǎn)換成ARC的代碼,刪除內(nèi)存管理操作(手動(dòng))
xcode提供了自動(dòng)將MRC轉(zhuǎn)換成ARC的功能,操作菜單欄edit -> Refacotor(重構(gòu)) -> Convert to Objective-C ARC
4.2> ARC>MRC
在ARC項(xiàng)目中繼續(xù)使用MRC編譯的類,在編譯選項(xiàng)中標(biāo)識(shí)MRC文件即可"-fno-objc-arc"
在MRC項(xiàng)目中繼續(xù)使用ARC編譯的類在編譯選項(xiàng)中標(biāo)識(shí)MRC文件即可"-fobjc-arc"
3.跨平臺(tái)
3> OC和C框架對(duì)象引用
oc和c 橋接 三個(gè)橋接關(guān)鍵字都是干么的 __bridge??不更改歸屬權(quán)??__bridge_transfer 所有權(quán)給OC?? __bridge_retain 解除OC的所有權(quán)
ios5/6/7/8 內(nèi)存方面的區(qū)別
ios5.自動(dòng)引用計(jì)數(shù)?(ARC)
ios6.UICollectionView?( 內(nèi)存重用機(jī)制,圖片展示瀑布流實(shí)現(xiàn) )??在didReceiveMemoryWarning中處理內(nèi)存(6之前在ViewDidUnload中)http://blog.csdn.net/likendsl/article/details/8199350
ios7.iOS7以后強(qiáng)制使用ARC
ios8
4、性能優(yōu)化
#warning 繼續(xù)優(yōu)化
怎么保證多人開發(fā)進(jìn)行內(nèi)存泄露的檢查.
使用Analyze進(jìn)行代碼的靜態(tài)分析
為避免不必要的麻煩,多人開發(fā)時(shí)盡量使用ARC
2.非自動(dòng)內(nèi)存管理情況下怎么做單例模式.
創(chuàng)建單例設(shè)計(jì)模式的基本步驟·
>聲明一個(gè)單件對(duì)象的靜態(tài)實(shí)例,并初始化為nil。
>創(chuàng)建一個(gè)類的類工廠方法,當(dāng)且僅當(dāng)這個(gè)類的實(shí)例為nil時(shí)生成一個(gè)該類的實(shí)例
>實(shí)現(xiàn)NScopying協(xié)議,覆蓋allocWithZone:方法,確保用戶在直接分配和初始化對(duì)象時(shí),不會(huì)產(chǎn)生另一個(gè)對(duì)象。
>覆蓋release、autorelease、retain、retainCount方法,以此確保單例的狀態(tài)。
>在多線程的環(huán)境中,注意使用@synchronized關(guān)鍵字或GCD,確保靜態(tài)實(shí)例被正確的創(chuàng)建和初始化。
3.對(duì)于類方法(靜態(tài)方法)默認(rèn)是autorelease的。所有類方法都會(huì)這樣嗎?
1>系統(tǒng)自帶的絕大數(shù)類方法返回的對(duì)象,都是經(jīng)過autorelease的
4.block在ARC中和MRC中的用法有什么區(qū)別,需要注意什么
1.對(duì)于沒有引用外部變量的Block,無論在ARC還是非ARC下,類型都是__NSGlobalBlock__,這種類型的block可以理解成一種全局的block,不需要考慮作用域問題。同時(shí),對(duì)他進(jìn)行Copy或者Retain操作也是無效的
2.應(yīng)注意避免循環(huán)引用
5.什么情況下會(huì)發(fā)生內(nèi)存泄漏和內(nèi)存溢出?
當(dāng)程序在申請(qǐng)內(nèi)存后,無法釋放已申請(qǐng)的內(nèi)存空間(例如一個(gè)對(duì)象或者變量使用完成后沒有釋放,這個(gè)對(duì)象一直占用著內(nèi)存),一次內(nèi)存泄露危害可以忽略,但內(nèi)存泄露堆積后果很嚴(yán)重,無論多少內(nèi)存,遲早會(huì)被占光。內(nèi)存泄露會(huì)最終會(huì)導(dǎo)致內(nèi)存溢出!
當(dāng)程序在申請(qǐng)內(nèi)存時(shí),沒有足夠的內(nèi)存空間供其使用,出現(xiàn)out of memory;比如申請(qǐng)了一個(gè)int,但給它存了long才能存下的數(shù),那就是內(nèi)存溢出。
6.[NSArray arrayWithobject:]這個(gè)方法添加對(duì)象后,需要對(duì)這個(gè)數(shù)組做釋放操作嗎?
不需要這個(gè)對(duì)象被放到自動(dòng)釋放池中
7.Json數(shù)據(jù)的解析,和解析數(shù)據(jù)的時(shí)候有內(nèi)存泄露嗎?有的話如何解
JSON解析的方案
SBJson
JSONkit
NSJSONSerialization
內(nèi)存泄漏么?
8.自動(dòng)釋放池底層怎么實(shí)現(xiàn)
自動(dòng)釋放池以棧的形式實(shí)現(xiàn):當(dāng)你創(chuàng)建一個(gè)新的自動(dòng)釋放池時(shí),它將被添加到棧頂。當(dāng)一個(gè)對(duì)象收到發(fā)送autorelease消息時(shí),它被添加到當(dāng)前線程的處于棧頂?shù)淖詣?dòng)釋放池中,當(dāng)自動(dòng)釋放池被回收時(shí),它們從棧中被刪除,并且會(huì)給池子里面所有的對(duì)象都會(huì)做一次release操作.