iOS晉級(jí)知識(shí)匯總(八)內(nèi)存管理

iOS的內(nèi)存管理

  • 內(nèi)存布局
  • 內(nèi)存管理方案
  • 數(shù)據(jù)結(jié)構(gòu)
  • ARC&MRC
  • 引用計(jì)數(shù)
  • 弱引用
  • 自動(dòng)釋放池
  • 循環(huán)引用

內(nèi)存布局

內(nèi)存分區(qū).png
  • stack區(qū)
    • 方法調(diào)用
  • heap區(qū) (堆區(qū))
    • alloc分配的一些對(duì)象
  • bss :未初始化的全局變量
  • data:已初始化的全局變量
  • text:程序代碼

內(nèi)存管理方案

  • TageedPointer
  • NONPOINTER_ISA
    • 64位 isa占64位,一般用30~40就夠用了,所以在剩余的位中做了內(nèi)存管理
  • 散列表 是復(fù)雜的數(shù)據(jù)結(jié)構(gòu)
    • 引用計(jì)數(shù)表
    • 弱引用表

內(nèi)存管理的分析全部都是基于開(kāi)源代碼的講解

NONPOINTER_ISA

arm64結(jié)構(gòu)下是64位

  • 第一位indexed
    • 0代表isa只是一個(gè)純的isa指針,里面內(nèi)容指向當(dāng)前的類(lèi)對(duì)象地址,
    • 1代表不單單是isa指針,還有一些關(guān)于內(nèi)存管理的一些數(shù)據(jù)
  • 第二位has_assoc
    • 0代表 沒(méi)有關(guān)聯(lián)對(duì)象
    • 1代表 有關(guān)聯(lián)對(duì)象
  • 第三位has_cxx_dtor 當(dāng)前對(duì)象是否用到c++
    • 0 沒(méi)有
    • 1 有
  • shiftcls 4 ~ 36 33位 比特位是類(lèi)對(duì)象的地址
    • 當(dāng)前類(lèi)對(duì)象的內(nèi)存地址
  • magic
  • weakly_referenced
    • 是否有弱引用指針
  • deallocating
    • 是否有dealloc的操作
  • has_sidetable_rc
    • 如果當(dāng)前的引用計(jì)數(shù)已經(jīng)達(dá)到上限,需要外掛一個(gè)has_sidetable_rc一個(gè)數(shù)據(jù)結(jié)構(gòu)去存儲(chǔ)相關(guān)的引用計(jì)數(shù)內(nèi)容
  • extra_rc 44~63 都是 extra_rc 引用計(jì)數(shù)
    • 引用計(jì)數(shù)在很小的范圍內(nèi),會(huì)直接存儲(chǔ)到isa這里,而不需要單獨(dú)的引用計(jì)數(shù)表來(lái)單獨(dú)存儲(chǔ)

散列表方式

  • sideTables()結(jié)構(gòu)
    • SideTable (數(shù)據(jù)結(jié)構(gòu))
    • 64個(gè)(非嵌入式系統(tǒng))

SideTable

散列表方式.png

為什么不是一個(gè)SideTable? 為什么要組成SideTables呢?

  • 對(duì)象可能需要在不同線程操作創(chuàng)建,這個(gè)時(shí)候進(jìn)行操作的時(shí)候需要進(jìn)行加鎖處理才能保證安全,這樣存在效率問(wèn)題
  • 用戶(hù)的內(nèi)存空間需要4gb,我們可以分配成千上萬(wàn)的引用對(duì)象,如果每個(gè)引用對(duì)象我們都要對(duì)齊進(jìn)行引用計(jì)數(shù)改變,都操作這張表就會(huì)出現(xiàn)效率問(wèn)題。如果一個(gè)對(duì)象操作這張表,會(huì)加鎖下一個(gè)對(duì)象需要在等上一個(gè)對(duì)象的鎖加完以后在處理,這就造成了效率低下的問(wèn)題
  • 系統(tǒng)為了解決這個(gè)效率低下,系統(tǒng)給我們提供了一個(gè)分離鎖的概念
  • 系統(tǒng)為我們分配了8個(gè)這個(gè)表(64位),這樣就可以并發(fā)的去修改引用解決問(wèn)題。

怎么樣實(shí)現(xiàn)快速分流?

SideTables的本質(zhì)是一張Hash表。
可能有64個(gè)SideTable存儲(chǔ)不同的引用計(jì)數(shù)表、和弱引用表

什么是hash算法

對(duì)象指針可以作為Key通過(guò)hash函數(shù)計(jì)算計(jì)算出hash表中你的value值的下標(biāo)也就是索引。

hash查找的過(guò)程

給定值是對(duì)象內(nèi)存地址,目標(biāo)是數(shù)組下標(biāo)索引。

給了一個(gè)對(duì)象的內(nèi)存地址,通過(guò)哈希函數(shù)的運(yùn)算,得到了一個(gè)集合的下標(biāo)索引值

對(duì)象的內(nèi)存地址指針 % 數(shù)組的count就可以得到這個(gè)數(shù)組中的索引

這樣就查找速度快了

散列表方案設(shè)計(jì)的數(shù)據(jù)結(jié)構(gòu)

  • Spinlock_t
    • 自旋鎖 是"忙等"的鎖,如果當(dāng)前鎖已經(jīng)被其他線程獲取,那么當(dāng)前線程會(huì)不斷的探測(cè)這個(gè)鎖是否被其他線程釋放,如果釋放自己第一時(shí)間去獲取這個(gè)鎖
    • 特點(diǎn):適合輕量訪問(wèn)(這個(gè)中+1 -1 計(jì)算邏輯不復(fù)雜的情況下稱(chēng)之為輕量)
  • 信號(hào)量
    • 當(dāng)前線程獲取不到鎖的時(shí)候,會(huì)把自己的線程阻塞休眠,等這個(gè)鎖被釋放的時(shí)候,會(huì)喚醒它獲取這個(gè)鎖

引用計(jì)數(shù)表

  • 實(shí)際上是一個(gè)refcountMap(hash表或者是字典),提高查找效率,存儲(chǔ)查找都是hsah,找到
    • size_t引用技術(shù)使用64位存儲(chǔ)的
    • 第一位是否有weak
    • 第二位是否deallocating

弱引用表

  • weak_table_t也是一張hash表,
    • 通過(guò)對(duì)象指針,hash算法的到我們的weak_entry_t的表
    • weak_entry_t里面存儲(chǔ)的就是弱引用指針。

MRC和ARC

MRC

手動(dòng)引用計(jì)數(shù),進(jìn)行內(nèi)存管理

  • alloc 分配一個(gè)對(duì)象的內(nèi)存空間
  • retain 引用計(jì)數(shù)加1
  • release 引用計(jì)數(shù)-1
  • retainCount 當(dāng)前引用計(jì)數(shù)的值
  • autorelease 會(huì)在autoreleasepool結(jié)束的時(shí)候,向其每一個(gè)對(duì)象發(fā)送release消息
  • dealloc 在MRC中需要顯示的調(diào)用super dealloc需要廢棄父類(lèi)的相關(guān)成員變量

ARC

什么事ARC

全名自動(dòng)引用計(jì)數(shù)

  • ARC是由LLVM和Runtime協(xié)作完成
  • ARC中禁止手動(dòng)調(diào)用retain、release、retainCount、dealloc、
    • 可以重寫(xiě)dealloc但是不能調(diào)用super dealloc
  • ARC中新增weak、strong屬性關(guān)鍵字

ARC和MRC的區(qū)別

  • MRC是手動(dòng)管理,ARC是LLVM和Runtime協(xié)作進(jìn)行自動(dòng)引用計(jì)數(shù)管理
  • MRC可以調(diào)用一些引用計(jì)數(shù)相關(guān)的+-1操作方法,而ARC是不能的
  • ARC有weak和strong

引用計(jì)數(shù)管理

實(shí)現(xiàn)原理分析

alloc實(shí)現(xiàn)

  • 經(jīng)過(guò)一些列調(diào)用,最終調(diào)用了C函數(shù)calloc(初始化完成會(huì)自己置0 而malloc是垃圾數(shù)據(jù))。
  • 此時(shí)并沒(méi)有設(shè)置引用計(jì)數(shù)為1

retain實(shí)現(xiàn)

  1. SideTable &table = SideTables()[this] 先獲取對(duì)應(yīng)的SideTable
  2. size_t & refcntStorage = table.refcnts[this]; 獲取到SideTable中的引用計(jì)數(shù)值
  3. refcntstorage += SIDE_TABLE_RC_ONE; 對(duì)其+1
    • SIDE_TABLE_RC_ONE不是1,前兩個(gè)位置是存儲(chǔ)弱引用計(jì)數(shù),和是否正在dealloc的,是后面62位,所以需要做一個(gè)偏移量。 所以說(shuō)是4.

release實(shí)現(xiàn)

  1. SideTable &table = SideTables()[this] 先獲取對(duì)應(yīng)的SideTable
  2. RefcountMap:iterator it = table.refcnts.find(this); 獲取到SideTable中的引用計(jì)數(shù)值
  3. it->second -= SIDE_TABLE_RC_ONE; 和retain正好相反

retainCount的實(shí)現(xiàn)

  1. SideTable &table = SideTables()[this] 先獲取對(duì)應(yīng)的SideTable
  2. size_t refcnt_result = 1; 聲明一個(gè)局部變量
  3. RefcountMap::iterator it = table.refcnts.find(this) 獲取到SideTable中的引用計(jì)數(shù)值,剛?cè)lloc的對(duì)象其實(shí)里面是為0的
  4. refcnt_result += it-> second >> SIDE_TABLE_RC_SHIFT 把查找的結(jié)果做一個(gè)向右偏移的操作,然后在+1

dealloc的實(shí)現(xiàn)

  • 調(diào)用_objc_rootDealloc
  • rootDealloc
  • 是否直接釋放的判斷標(biāo)準(zhǔn)
    • nonpointer_isa 是否是非指針型的isa指針
    • weakly_referenced 是否有weak指針指向它
    • has_assoc 當(dāng)前對(duì)象是否有關(guān)連對(duì)象
    • has_cXX_dtor 是否使用了C++相關(guān)的代碼,是否ARC
    • has_sidetable_rc 是否是通過(guò)sidtable表來(lái)存儲(chǔ)的。
  • 以上都不是 就可以釋放,如果可以就使用c函數(shù)的free函數(shù)釋放
  • 如果不可以就使用object_dispose函數(shù)來(lái)進(jìn)行后續(xù)的處理,然后結(jié)束
dealloc的內(nèi)部實(shí)現(xiàn).png

object_dispose實(shí)現(xiàn)

  • objc_destructInstance
  • C函數(shù)的free
  • 結(jié)束
dealloc內(nèi)部實(shí)現(xiàn)中dispose函數(shù).png

objc_destructInstance的實(shí)現(xiàn)

  • 是否有C++或者是否有ARC
    • YES object_cxxDestruct
    • NO 調(diào)用AssociatedObjects
  • 如果沒(méi)有C++或者ARC 就調(diào)用AssociatedObjects方法
    • YES _object_remove_assocations()
    • NO clearDealloccating
  • _object_remove_assocations,以后還是沒(méi)有關(guān)聯(lián)對(duì)象那么都會(huì)調(diào)用clearDealloccating結(jié)束objc_destructInstance方法。
objc_destructInstance函數(shù)實(shí)現(xiàn).png

clearDealloccating的實(shí)現(xiàn)

  • sidetable_clearDeallocating
  • weak_clear_no_lock
    • 將指向該對(duì)象的弱引用指針置為nil
  • table.refcnts.erase
    • 從引用計(jì)數(shù)表中擦除該對(duì)象的引用計(jì)數(shù)
clearDealloccating.png

弱引用管理

弱引用調(diào)用棧

弱引用調(diào)用棧.png
  • 一個(gè)被聲明為_(kāi)_weak弱引用的指針,經(jīng)過(guò)編譯器編譯以后,會(huì)調(diào)用objc_initWeak方法,經(jīng)過(guò)一系列的函數(shù)調(diào)用棧,會(huì)調(diào)用weak_register_no_lock這個(gè)函數(shù),進(jìn)行弱引用變量的添加。

  • 具體添加的位置,是通過(guò)一個(gè)hash算法來(lái)進(jìn)行進(jìn)行位置查找的,

  • 如果說(shuō)我們查找位置當(dāng)中已經(jīng)有了當(dāng)前對(duì)象所有的弱引用數(shù)組,我們新的弱引用變量添加到引用數(shù)組當(dāng)中,如果沒(méi)有弱引用數(shù)組,那么就創(chuàng)建一個(gè)新的弱引用數(shù)組,然后第0個(gè)位置添加wek指針,后面的都置為0。

當(dāng)清除weak變量 通知設(shè)置指向?yàn)閚il, 它是如何置nil的

如何將weak自動(dòng)置為nil.png

完整過(guò)程

  • 通過(guò)被廢棄對(duì)象的指針經(jīng)過(guò)hash算法的到,求出弱引用數(shù)組對(duì)應(yīng)的數(shù)組索引位置,然后通過(guò)這個(gè)索引返回給對(duì)象我這個(gè)弱引用數(shù)組
  • 如果弱引用數(shù)組為空,不做操作
  • 如果弱引用數(shù)組不為空遍歷這個(gè)數(shù)組,如果數(shù)組中的指針就是被廢棄的弱引用指針那么就將其置為nil。

總結(jié)

  • 當(dāng)一個(gè)對(duì)象被dealloc之后,dealloc內(nèi)部的實(shí)現(xiàn)會(huì)去調(diào)用弱引用清除這個(gè)函數(shù)
  • 然后函數(shù)會(huì)通過(guò),當(dāng)前對(duì)象指針查找弱引用表 ,把一個(gè)對(duì)象的所有弱引用表都拿出來(lái),是一個(gè)數(shù)組
  • 編譯所有這個(gè)數(shù)組當(dāng)中的弱引用指針?lè)謩e置為nil

自動(dòng)釋放池

自動(dòng)釋放池的面試題.png

編譯器改寫(xiě)

  • objc_autoreleasepoolPush()和objc_autoreleasePoolPop中間是代碼
  • push返回值是一個(gè)無(wú)類(lèi)型的指針
  • objc_autoreleasePoolPop需要這個(gè)無(wú)類(lèi)型指針作為標(biāo)記也就是push返回的無(wú)類(lèi)型的指針


    autoreleasePool改寫(xiě).png

objc_autoreleasepoolPush和objc_autoreleasePoolPop的函數(shù)調(diào)用棧

  • 內(nèi)部會(huì)調(diào)用AutoreleasePoolPage::push方法
  • AutoreleasePoolPage::pop方法
    • 一次Pop當(dāng)然于一次批量的Pop操作(AutoreleasePool中的對(duì)象都會(huì)放入到自動(dòng)釋放池中當(dāng)Pop之后,AutoreleasePool中的對(duì)象的對(duì)象都會(huì)發(fā)送一次release消息所以是批量操作)

自動(dòng)釋放池的數(shù)據(jù)結(jié)構(gòu)

  • 以棧為節(jié)點(diǎn)通過(guò)雙向鏈表的形式組合而成
  • 適合線程一一對(duì)應(yīng)的。

AtuoreleasePoolPage的數(shù)據(jù)結(jié)構(gòu)

  • id*next
    • 當(dāng)前棧的空的位置
  • autoreleasePollPage * const parent;
    • 鏈表的父指針
  • autoreleasePollPage *child;
    • 鏈表的孩子指針
  • pthread_t const thread;
    • 與線程一一對(duì)應(yīng)的

AtuoreleasePoolPage::Push

AutoreleasePoolpagePush操作的原理.png

autorelease

autorelease的實(shí)現(xiàn)過(guò)程.png
  • 一個(gè)對(duì)象調(diào)用了autorelease方法,這個(gè)對(duì)象添加到next指針之后,next移動(dòng)到新的位置,下一個(gè)調(diào)用autorelease方法的對(duì)象就會(huì)添加到這個(gè)位置

AtuoreleasePoolPage::Pop

  • 根據(jù)傳入的哨兵對(duì)象找到對(duì)應(yīng)位置
  • 給上次Push操作之后添加的對(duì)象依次發(fā)送release消息(next指針到哨兵對(duì)象之間的對(duì)象依次發(fā)送release消息)
  • 回退指針搭配正確位置
AutoreleasePoolpagePop的原理操作.png

雙向鏈表的概念

雙向鏈表的結(jié)構(gòu).png

棧結(jié)構(gòu)概念

棧結(jié)構(gòu).png

面試題自動(dòng)釋放池的實(shí)現(xiàn)結(jié)構(gòu)是什么?

  • 以棧為節(jié)點(diǎn)通過(guò)雙向鏈表的形式組合而成

自動(dòng)釋放池的總結(jié)

下面代碼什么時(shí)候釋放

viewdidload{
    NSMutableArray *array = [NSSmutableArray array];
}

  • 在當(dāng)次runloop將要結(jié)束的時(shí)候調(diào)用AutoreleasePoolPage::Pop()
    • 每一次runloop循環(huán)將要結(jié)束的時(shí)候都會(huì)對(duì)前一次創(chuàng)建的autoreleasePool進(jìn)行Pop操作,同時(shí)會(huì)Push進(jìn)來(lái)一個(gè)新的autoreleasePool
    • viewdidload創(chuàng)建的對(duì)象,是在當(dāng)次runloop將要結(jié)束的時(shí)候,調(diào)用autoreleasePoolpage::Pop方法時(shí)候,把對(duì)應(yīng)的array對(duì)象調(diào)用它的release方法。

多次嵌套就是多次插入哨兵對(duì)象

關(guān)于autoreleasepool為和可以嵌套調(diào)用?

實(shí)際上多次嵌套插入哨兵對(duì)象,每次進(jìn)行autoreleasePool的代碼塊創(chuàng)建的時(shí)候,假如autoreleasePoolpage沒(méi)有滿的情況下,系統(tǒng)就會(huì)在當(dāng)前autoreleasePoolpage棧中進(jìn)行一次哨兵對(duì)象的插入,如果滿了會(huì)創(chuàng)建一個(gè)新的autoreleasePoolpage,然后當(dāng)前的autoreleasePoolpage中的child指針指向新創(chuàng)建的autoreleasePoolpage。

所以autoreleasepool可以多層嵌套調(diào)用

循環(huán)引用

三種循環(huán)引用:

  • 自循環(huán)引用
  • 相互循環(huán)引用
  • 多循環(huán)引用(大環(huán))

自循環(huán)引用

自循環(huán)引用.png

相互循環(huán)引用

相互循環(huán)引用.png

多循環(huán)引用(大環(huán))

大環(huán)循環(huán)引用(多循環(huán)引用).png

如何破除循環(huán)引用?

  • 避免產(chǎn)生循環(huán)引用
  • 在合適的時(shí)機(jī)手動(dòng)斷環(huán)

具體解決方案:

  • __weak
  • __block
  • __unsafe_unretained

__weak 破解循環(huán)引用

__weak避免產(chǎn)生循環(huán)引用.png

__block破解* 破解循環(huán)引用

  • MRC __block修飾對(duì)象不會(huì)增加其引用計(jì)數(shù),避免了循環(huán)引用
  • ARC __block修飾對(duì)象會(huì)被強(qiáng)引用,無(wú)法避免循環(huán)引用,需手動(dòng)解環(huán)

__unsafe_unretained 破解循環(huán)引用

  • 修飾對(duì)象不會(huì)增加引用計(jì)數(shù),避免了循環(huán)引用
  • 如果被修飾對(duì)象在某一時(shí)機(jī)被釋放,會(huì)產(chǎn)生懸垂指針,懸垂指針又可能會(huì)出現(xiàn)不可預(yù)見(jiàn)的問(wèn)題

循環(huán)引用示例

在開(kāi)發(fā)過(guò)程中,你遇到過(guò)哪些循環(huán)引用問(wèn)題,你又是如何解決的?

  • Block的使用示例

  • NSTimer的循環(huán)引用問(wèn)題

有一個(gè)頁(yè)面有一個(gè)banner滾動(dòng)欄,每3秒滾到一次。一般有一個(gè)banner對(duì)象,VC對(duì)它強(qiáng)持有,
banner對(duì)象的需求是每3秒滾動(dòng)一次。需要添加一個(gè)NSTimer,當(dāng)我向banner對(duì)象添加回調(diào)的時(shí)候,NSTimer會(huì)對(duì)banner對(duì)象施加一個(gè)強(qiáng)引用,這個(gè)時(shí)候就產(chǎn)生了相互循環(huán)引用問(wèn)題。

實(shí)際上,NSTimer創(chuàng)建完成以后會(huì)有一個(gè)主線程RunLoop去強(qiáng)引用NSTimer強(qiáng)引用。就算是VC退出釋放掉,那么banner對(duì)象也不會(huì)釋放,因?yàn)橹骶€程runLoop強(qiáng)引用了這個(gè)對(duì)象。

NSTimer有重復(fù),以及非重復(fù)定時(shí)器,假如是非重復(fù)定時(shí)器,那么在NSTimer回調(diào)完成以后設(shè)置無(wú)效并置nil,那么就破解了循環(huán)引用。

假如NSTimer重復(fù)多次回調(diào)

第一種:在NSTimer和Banner之間設(shè)置一個(gè)中間對(duì)象,這個(gè)中間對(duì)象分別弱引用NSTimer和banner對(duì)象。那么當(dāng)VC釋放掉,banner對(duì)象也就釋放掉了,NSTimer的回調(diào)會(huì)去中間對(duì)象,而中間對(duì)象只要判斷banner對(duì)象為不為nil 如果為nil就直接無(wú)效化NSTimer。

NSTimer的循環(huán)引用問(wèn)題.png

考點(diǎn)

  • 代理
  • Block
  • NSTimer
  • 大環(huán)引用

面試題總結(jié)

如果我們對(duì)一個(gè)類(lèi)添加了關(guān)聯(lián)對(duì)象,那么在這個(gè)類(lèi)被釋放以后會(huì)清除掉這個(gè)關(guān)聯(lián)對(duì)象嗎?

會(huì)的,因?yàn)橄到y(tǒng)在dealloc中釋放了關(guān)聯(lián)對(duì)象

關(guān)于autoreleasepool為和可以嵌套調(diào)用?

實(shí)際上多次嵌套插入哨兵對(duì)象,每次進(jìn)行autoreleasePool的代碼塊創(chuàng)建的時(shí)候,假如autoreleasePoolpage沒(méi)有滿的情況下,系統(tǒng)就會(huì)在當(dāng)前autoreleasePoolpage棧中進(jìn)行一次哨兵對(duì)象的插入,如果滿了會(huì)創(chuàng)建一個(gè)新的autoreleasePoolpage,然后當(dāng)前的autoreleasePoolpage中的child指針指向新創(chuàng)建的autoreleasePoolpage。

autoreleasePool的應(yīng)用場(chǎng)景

在for循環(huán)中alloc圖片數(shù)據(jù)等內(nèi)存消耗較大的場(chǎng)景手動(dòng)插入autoreleasePool。

autoreleasePool的實(shí)現(xiàn)原理是什么?

autoreleasePool實(shí)現(xiàn)原理:

  • 以棧為節(jié)點(diǎn),通過(guò)雙向鏈表的形式組合而成的數(shù)據(jù)結(jié)構(gòu)

什么是ARC

  • ARC是由LLVM編譯器以及runtime協(xié)作來(lái)為我們實(shí)現(xiàn)自動(dòng)引用計(jì)數(shù)的管理

為什么weak指針指向的對(duì)象在廢棄之后會(huì)被自動(dòng)置為nil

當(dāng)對(duì)象在被廢棄之后,dealloc的內(nèi)部方法實(shí)現(xiàn)當(dāng)中會(huì)調(diào)用清除弱引用的方法,然后在清除弱引用的方法中會(huì)通過(guò)hash算法來(lái)查找被廢棄對(duì)象在弱引用表當(dāng)中的位置來(lái)提取它所對(duì)的人用引用指針的列表數(shù)組,然后進(jìn)行for循環(huán)遍歷,把每一個(gè)弱引用指針都置為nil

蘋(píng)果是如何實(shí)現(xiàn)AutoreleasePool

AutoreleasePool是以棧為節(jié)點(diǎn),雙向鏈表形式來(lái)合成的數(shù)據(jù)結(jié)構(gòu)。

什么是循環(huán)引用?你遇到過(guò)哪些循環(huán)引用,是怎么解決的?

  • 自循環(huán)引用
  • 雙向循環(huán)引用
  • 大環(huán)引用

比如說(shuō)NStimer的循環(huán)引用。

最后編輯于
?著作權(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)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

  • iOS 內(nèi)存管理知識(shí)梳理 一、內(nèi)存泄漏 1、檢測(cè)方式:Memory Leaks、Alloctions、Analys...
    如今0生活成了心術(shù)閱讀 962評(píng)論 0 3
  • 前言 iOS 的內(nèi)存管理不止是 「引用計(jì)數(shù)表」。 iOS 開(kāi)發(fā)者基本都知道 iOS 是通過(guò)「引用計(jì)數(shù)」來(lái)管理內(nèi)存的...
    r_瑞閱讀 395評(píng)論 0 1
  • IOS 內(nèi)存管理 1.垃圾回收機(jī)制 和引用計(jì)數(shù)機(jī)制 垃圾回收機(jī)制:定期查找不再使用的對(duì)象,釋放對(duì)象占用的內(nèi)存 引用...
    IOS_Faker閱讀 196評(píng)論 0 0
  • 內(nèi)存布局 內(nèi)存區(qū)域: 內(nèi)核區(qū)(low) - 程序加載 - 保留(high)程序:未初始化數(shù)據(jù)(.bss)已初始化數(shù)...
    奮斗的老王閱讀 1,228評(píng)論 0 50
  • iOS OC對(duì)象的內(nèi)存管理 在iOS中,使用引用計(jì)數(shù)來(lái)管理OC對(duì)象內(nèi)存 一個(gè)新創(chuàng)建的OC對(duì)象引用計(jì)數(shù)默認(rèn)是1,當(dāng)引...
    喜歡w閱讀 644評(píng)論 0 1

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