1.程序員
什麼狀況下會發生內存泄漏和內存溢出?安全
答:當程序在申請內存後,沒法釋放已申請的內存空間(例如一個對象或者變量使用完成後沒有釋放,這個對象一直佔用着內存),一次內存泄露危害能夠忽略,但內存泄露堆積後果很嚴重,不管多少內存,早晚會被佔光。內存泄露會最終會致使內存溢出!數據結構
當程序在申請內存時,沒有足夠的內存空間供其使用,出現out of memory;好比申請了一個int,但給它存了long才能存下的數,那就是內存溢出。多線程
2.併發
自動釋放池底層怎麼實現函數
答:自動釋放池以棧的形式實現:當你建立一個新的自動釋放池時,它將被添加到棧頂。當一個對象收到發送autorelease消息時,它被添加到當前線程的處於棧頂的自動釋放池中,當自動釋放池被回收時,它們從棧中被刪除, 而且會給池子裏面全部的對象都會作一次release操做.性能
3atom
簡述OC中 內存管理機制。與retain配對使用的方法是dealloc仍是release,爲何?須要與alloc配對使用的方法是dealloc仍是 release,爲什 麼?readwrite,readonly,assign,retain,copy,nonatomic,atomic,strong,weak屬性的做 用?spa
答:OC中內存管理機制應該就是引用計數的增減吧,retainCount爲0時釋放該內存。線程
retain對應的是release,內存的釋放用release。
alloc對應的是dealloc,內存的銷燬用dealloc。
readwrite此標記說明屬性會被當成讀寫的,這也是默認屬性。
readonly此標記說明屬性只能夠讀,也就是不能設置,能夠獲取。
assign不會使引用計數加1,也就是直接賦值。
retain會使引用計數加1。
copy創建一個索引計數爲1的對象,在賦值時使用傳入值的一份拷貝。
nonatomic:非原子性訪問,多線程併發訪問會提升性能。
atomic:原子性訪問。
strong:打開ARC時纔會使用,至關於retain。
weak:打開ARC時纔會使用,至關於assign,能夠把對應的指針變量置爲nil。
4.
堆棧的區別:
答:(1)管理方式:對於棧來說,是由編譯器自動管理,無需咱們手工控制;對於堆來講,釋放工做由程序員控制,容易產生 memory leak。
(2)申請大小:能從棧得到的空間較小,堆是向高地址擴展的數據結構,是不連續的內存區域。堆的大小受限於計算機系統中 有效的虛擬內存。因而可知,堆得到的空間比較靈活,也比較大。
(3)碎片問題:對於堆來說,頻繁的new/delete勢必會形成內存空間的不連續,從而形成大量的碎片,使程序效率下降。 對於棧來說,則不會存在這個問題,由於棧是先進後出的隊列,他們是如此的一一對應,以致於永遠都不可能有一個內存塊 從棧中間彈出
(4)分配方式:堆都是動態分配的,沒有靜態分配的堆。棧有2種分配方式:靜態分配和動態分配。靜態分配是編譯器完成 的,好比局部變量的分配。動態分配由 alloca函數進行分配,可是棧的動態分配和堆是不一樣的,他的動態分配是由編譯器 進行釋放,無需咱們手工實現。
(5)分配效率:棧是機器系統提供的數據結構,計算機會在底層對棧提供支持:分配專門的寄存器存放棧的地址,壓棧出棧 都有專門的指令執行,這就決定了棧的效率比較高。堆則是C/C++函數庫提供的,它的機制是很複雜的。
5.
分別描述內存管理要點、autorelease、release、NSAutoreleasePool?並說明autorelease是什 麼時候被release的?簡述何時由你負責釋放對象,何時不禁你釋放?
[NSAutoreleasePool release]和[NSAutoreleasePool drain]有什麼區別?
內存管理要點:
Objective-C 使用引用計數機制(retainCount)來管理內存。內存每被引用一次,該內存的引用計數+1,每被釋放一次引 用計數-1。當引用計數 = 0 的時候,調用該對象的 dealloc 方法,來完全從內存中刪除該對象。 alloc,allocWithZone,new(帶初始化)時:該對象引用計數 +1;
retain:手動爲該對象引用計數 +1;
copy:對象引用計數 +1;
mutableCopy:生成一個新對象,新對象引用計數爲 1;
release:手動爲該對象引用計數 -1; autorelease:把該對象放入自動釋放池,當自動釋放池釋放時,其內的對象引用計數 -1。
NSAutoreleasePool: NSAutoreleasePool是經過接收對象向它發送的autorelease消息,記錄該對象的release消息,當自動釋放池被銷燬 時,會自動向池中的對象發送release消息。
autorelease 是在自動釋放池被銷燬,向池中的對象發送release
只能釋放本身擁有的對象, 區別是:在引用計數環境下(在不使用ARC狀況下),二者基本同樣,在GC環境下,release 是一個no-op(無效操 做),因此不管是否是gc都使用drain
6.
IPhone OS有沒有垃圾回收?autorelease 和垃圾回收制(gc)有什麼關係?
答:沒有。autorelease只是延遲釋放,gc是每隔一段時間詢問程序,看是否有無指針指向的對象,如有,就將它回收。他們 二者沒有什麼關係。
7.
爲何不少內置類如UITableViewController的delegate屬性都是assign而不是retain的? 會引發循環引用----如果retain,在alloc一次以後,若release一次,會致使內存泄漏,若release兩次會致使兩個 對象的dealloc嵌套執行,結果就是都沒有執行成功,最後崩潰! 全部的引用計數系統,都存在循環應用的問題。
答:例以下面的引用關係:
* 對象a建立並引用到了對象b.
* 對象b建立並引用到了對象c.
* 對象c建立並引用到了對象b.
這時候b和c的引用計數分別是2和1。 當a再也不使用b,調用release釋放對b的全部權,由於c還引用了b,因此b的引用計數爲1,b不會被釋放。 b不釋放,c的引用計數就是1,c也不會被釋放。今後,b和c永遠留在內存中。 這種狀況,必須打斷循環引用,經過其餘規則來維護引用關係。咱們常見的delegate每每是assign方式的屬性而不是 retain方式 的屬性,賦值不會增長引用計數,就是爲了防止delegation兩端產生沒必要要的循環引用。 若是一個UITableViewController 對象a經過retain獲取了UITableView對象b的全部權,這個UITableView對象b的 delegate又是a,若是這個delegate是retain方式的,那基本上就沒有機會釋放這兩個對象了。本身在設計使用 delegate模式時,也要注意這點。
8.
深拷貝和淺拷貝的理解?
答:對一個實例進行深拷貝時當前類須要實現NSCopying協議。 淺拷貝是複製出來一個跟原對象是同一地址的對象,而深拷貝則是複製出來一個跟源對象不一樣地址的對象,改變原對象,對新對象沒有影響。
9.
什麼是安全釋放?
答:把對象指針置爲nil,再對其釋放。
10.
談談你對iOS內存管理的理解
答:在Objective-C2.0以後引入了垃圾回收機制(GC),可是隻是在MAC OS X系統下,iOS下沒有垃圾回收。
Objective-C採用了引用計數的機制來管理對象,引用計數的值表示幾個對象在使用它,當對象的引用計數爲0的時候,系統負責對象的銷燬。能夠表述爲:一、本身生產的對象(你能夠經過alloc(allocWithZone)、new、copy、mutableCopy或者是以這幾個單詞開頭的方法建立對象),本身持有;二、非本身生產的對象,本身也能持有(使用retain);三、不須要持有的對象,本身負責釋放(release、autorelease);四、非本身持有的對象,沒法釋放。內存管理的方式有兩種:MRC(手動管理引用計數)和ARC(自動管理引用計數:編譯器會在適當的地方插入retain、release、autorelease)。
11.
簡述OC中內存管理機制
答:1.內存管理分爲ARC和MRC兩大方面,採用引用計數機制管理內存
2.MRC方面分爲,創造一個對象時會採用allco方法,這時這對象的引用計數爲1,咱們稱爲這個對象的對象全部權爲1,增長一個對象引用計數的方法還有retain,copy,add等於減小一個對象引用計數的方法爲release和autorelease,當一個對象的引用計數減小的方法,使其保持平衡。當一個對象的引用計數爲1的時候,咱們在調用release或者autorelease的時候,系統會自動調用dealloc方法,釋放對象所佔資源。
3.ARC方面,其採用的也是引用計數機制,其原理和MRC同樣,只不過把MRC中咱們本身管理內存的方式交給了編譯器來管理,仍然須要管理內存。
4.屬性修飾詞方面:其屬性修飾詞中和內存有關的,retain,assign,copy,weak,strong其中retain,會使其對象的引用計數加1,assign只是簡單的賦值,不會引發引用計數增長,copy分爲兩種狀況:1.深copy會對和淺copy至關於retain,深copy會對copy出來的對象重新開闢一塊內存空間,須要對copy出來的對象單獨作內存管理。而weak是在ARC中使用的修飾詞,其做用至關於assign,可是它有一點比較好的是assign修飾對象爲空時,其指針指向nil,防止野指針的出現,strong至關於retain。