iOS內(nèi)存劃分

一,RAM和ROM的介紹

RAM與ROM就是具體的存儲空間,統(tǒng)稱為存儲器。

RAM(random access memory):運行內(nèi)存,CPU可以直接訪問,讀寫速度非??欤遣荒艿綦姶鎯ΑK址譃椋?/p>

  • 動態(tài)DRAM,速度慢一點,需要定期的刷新(充電),我們常說的內(nèi)存條就是指它,價格會稍低一點,手機中的運行內(nèi)存也是指它。
  • 靜態(tài)SRAM,速度快,我們常說的一級緩存,二級緩存就是指它,當然價格高一點。

ROM(read only memory):存儲性內(nèi)存,可以掉電存儲,例如SD卡、Flash(機械磁盤也可以簡單的理解為ROM)。用的多的:NandFlash,還有NorFlash,現(xiàn)在用的已經(jīng)比較少了(兩者主要區(qū)別是前者空間大,便宜,后者可以直接運行程序,讀取速度快)。

由于RAM類型不具備掉電存儲能力(即一停止供電數(shù)據(jù)全沒了,從新上電后全是亂碼,所以需要初始化),所以app程序一般存放于ROM中。RAM的訪問速度要遠高于ROM,價格也要高。

RAM與ROM協(xié)同工作
由于RAM不能掉電存儲,所以我們的APP程序,刷機包,下載的文件等等,都是在ROM里面存儲的。

手機里面使用的ROM基本都是NandFlash,CPU是不能直接訪問的,而是需要文件系統(tǒng)/驅(qū)動程序(嵌入式中的EMC)將其讀到RAM里面,CPU才可以訪問。另外,RAM的速度也比NandFlash快。

二,內(nèi)存劃分區(qū)域

Objective-C從名字來看就可以知道這是一門超C語言,所以了解C語言的內(nèi)存模型對于理解Objective-C的內(nèi)存管理、性能優(yōu)化有很大的幫助。C語言內(nèi)存結(jié)構如下:


C語言內(nèi)存結(jié)構圖.png

而Objcective-C 的結(jié)構如下:


iOS內(nèi)存劃分圖片.png

以上就是相關的iOS內(nèi)存劃分的五個區(qū)域,接下來讓我們具體分析一下每個區(qū)域所起到的作用是什么?分別在iOS開發(fā)過程擔任了什么作用。

2.1 棧區(qū)

傳入函數(shù)的參數(shù)值、函數(shù)體內(nèi)聲明的局部變量等,由編譯器自動分配釋放,通常在函數(shù)執(zhí)行結(jié)束后就釋放了。(注意:不包括static修飾的變量,static意味該變量存放在全局/靜態(tài)區(qū))其操作方式類似數(shù)據(jù)結(jié)構中的棧,先進后出。

棧內(nèi)存分配運算內(nèi)置于處理器的指令集,效率很高,但是分配的內(nèi)存容量有限,比如iOS中棧區(qū)的大小是2M(看網(wǎng)上說,也有人說1M,我也不知道具體大小,但棧區(qū)的內(nèi)存肯定不會太大)。

  • 存放的局部變量、先進后出、一旦出了作用域就會被銷毀;函數(shù)跳轉(zhuǎn)地址,現(xiàn)場保護等;
  • 程序猿不需要管理棧區(qū)變量的內(nèi)存
  • 棧區(qū)地址從高到低分配;

2.2堆區(qū)

堆區(qū)的內(nèi)存是由代碼分配和釋放,用于存放進程運行中被動態(tài)分配的內(nèi)存段,堆區(qū)的大小并不固定,可動態(tài)擴張或縮減。

  • 變量通過new、alloc、malloc、realloc分配的內(nèi)存塊就存放在堆區(qū)。
  • 堆區(qū)的內(nèi)存都是動態(tài)分配的。
  • 當進程調(diào)用alloc等函數(shù)分配內(nèi)存時,新分配的內(nèi)存就被動態(tài)添加到堆上(堆被擴張)。
  • 當利用realse釋放內(nèi)存時,被釋放的內(nèi)存從堆中被剔除(堆被縮減)。
  • 如果應用程序沒有釋放掉,操作系統(tǒng)會自動回收,分配方式類似于鏈表。
  • 因為現(xiàn)在iOS基本都使用ARC來管理對象,所以也不需要手動釋放。
  • 一般速度比較慢,而且容易產(chǎn)生內(nèi)存碎片,不過用起來最方便。

2.3 全局/靜態(tài)區(qū)域

全局/靜態(tài)區(qū)是存放全局變量和靜態(tài)變量的。
已初始化的全局變量和靜態(tài)變量存放在一塊區(qū)域。
未初始化的全局變量和靜態(tài)變量在相鄰的另一塊區(qū)域。
由static修飾的變量會成為靜態(tài)變量,該變量的內(nèi)存由全局/靜態(tài)區(qū)在編譯階段完成分配,且僅分配一次。
static可以修飾局部變量也可以修飾全局變量。
全局/靜態(tài)區(qū)的內(nèi)存在編譯階段完成分配,程序運行時會一直存在內(nèi)存中,只有當程序結(jié)束后才會由操作系統(tǒng)釋放。

2.4 常量區(qū)

常量區(qū)是一塊比較特殊的存儲區(qū),常量區(qū)里面存放的是常量,常量字符串就存放在常量區(qū)。
常量區(qū)的內(nèi)存在編譯階段完成分配,程序運行時會一直存在內(nèi)存中,只有當程序結(jié)束后才會由操作系統(tǒng)釋放。

2.5 代碼區(qū)

代碼區(qū)是用來存放可執(zhí)行文件的操作指令(存放函數(shù)的二進制代碼),其實就是存放程序的所有代碼。代碼區(qū)需要防止在運行時被非法修改,所以只準許讀取操作,而不允許寫入(修改)操作——它是不可寫的。

通常代碼段是可共享的,這使得需要頻繁被執(zhí)行的程序只需要在內(nèi)存中擁有一份拷貝即可。代碼段也通常是只讀的,這樣可以防止其他程序意外地修改其指令。另外,代碼段還規(guī)劃了局部數(shù)據(jù)所申請的內(nèi)存空間信息。 代碼段(code segment/text segment)通常是指用來存放程序執(zhí)行代碼的一塊內(nèi)存區(qū)域。這部分區(qū)域的大小在程序運行前就已經(jīng)確定,并且內(nèi)存區(qū)域通常屬于只讀, 某些架構也允許代碼段為可寫,即允許修改程序。在代碼段中,也有可能包含一些只讀的常數(shù)變量,例如字符串常量等。

三,總結(jié)

在編譯階段代碼區(qū)、常量區(qū)、全局/靜態(tài)區(qū)就已經(jīng)分配完成并且大小固定,所以指向這些區(qū)的指針不會產(chǎn)生崩潰性的錯誤。
而棧區(qū)和堆區(qū)內(nèi)存分配隨著程序運行而變化(堆的創(chuàng)建銷毀,棧的彈入彈出)。
在iOS中,堆區(qū)的內(nèi)存是應用程序共享的,堆區(qū)的內(nèi)存分配是系統(tǒng)負責的。

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

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