九色国产,午夜在线视频,新黄色网址,九九色综合,天天做夜夜做久久做狠狠,天天躁夜夜躁狠狠躁2021a,久久不卡一区二区三区

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
程序內(nèi)存分區(qū)

文章目錄

內(nèi)存分區(qū)

程序運行之前

我們要想執(zhí)行我們編寫的c程序,那么第一步需要對這個程序進行編譯。

  1. 預處理:宏定義展開、頭文件展開、條件編譯,這里并不會檢查語法
  2. 編譯:檢查語法,將預處理后文件編譯生成匯編文件
  3. 匯編:將匯編文件生成目標文件(二進制文件)
  4. 鏈接:將目標文件鏈接為可執(zhí)行程序

當我們編譯完成生成可執(zhí)行文件之后,我們通過在linux下size命令可以查看一個可執(zhí)行二進制文件基本情況:

通過上圖可以得知,在沒有運行程序前,也就是說程序沒有加載到內(nèi)存前,可執(zhí)行程序內(nèi)部已經(jīng)分好3段信息,分別為代碼區(qū)(text)、數(shù)據(jù)區(qū)(data)未初始化數(shù)據(jù)區(qū)(bss) 3 個部分(有些人直接把data和bss合起來叫做靜態(tài)區(qū)或全局區(qū))。

代碼區(qū)

存放 CPU 執(zhí)行的機器指令。

通常代碼區(qū)是可共享的(即另外的執(zhí)行程序可以調(diào)用它),使其可共享的目的是對于頻繁被執(zhí)行的程序,只需要在內(nèi)存中有一份代碼即可。代碼區(qū)通常是只讀的,使其只讀的原因是防止程序意外地修改了它的指t令。另外,代碼區(qū)還規(guī)劃了局部變量的相關信息。

全局初始化數(shù)據(jù)區(qū)/靜態(tài)數(shù)據(jù)區(qū)(data段)

該區(qū)包含了在程序中明確被初始化的全局變量、已經(jīng)初始化的靜態(tài)變量(包括全局靜態(tài)變量和t)和常量數(shù)據(jù)(如字符串常量)。

未初始化數(shù)據(jù)區(qū)(又叫 bss 區(qū))

存入的是全局未初始化變量和未初始化靜態(tài)變量。未初始化數(shù)據(jù)區(qū)的數(shù)據(jù)在程序開始執(zhí)行之前被內(nèi)核初始化為 0 或者空(NULL)。

總體來講說,程序源代碼被編譯之后主要分成兩種段:程序指令(代碼區(qū))和程序數(shù)據(jù)(數(shù)據(jù)區(qū))。代碼段屬于程序指令,而數(shù)據(jù)域段和.bss段屬于程序數(shù)據(jù)。

問題:那為什么把程序的指令和程序數(shù)據(jù)分開呢?

  • 程序被load到內(nèi)存中之后,可以將數(shù)據(jù)和代碼分別映射到兩個內(nèi)存區(qū)域。由于數(shù)據(jù)區(qū)域?qū)M程來說是可讀可寫的,而指令區(qū)域?qū)Τ绦騺碇v說是只讀的,所以分區(qū)之后呢,可以將程序指令區(qū)域和數(shù)據(jù)區(qū)域分別設置成可讀可寫或只讀。這樣可以防止程序的指令有意或者無意被修改;
  • 當系統(tǒng)中運行著多個同樣的程序的時候,這些程序執(zhí)行的指令都是一樣的,所以只需要內(nèi)存中保存一份程序的指令就可以了,只是每一個程序運行中數(shù)據(jù)不一樣而已,這樣可以節(jié)省大量的內(nèi)存。比如說之前的Windows Internet Explorer 7.0運行起來之后, 它需要占用112 844KB的內(nèi)存,它的私有部分數(shù)據(jù)有大概15 944KB,也就是說有96 900KB空間是共享的,如果程序中運行了幾百個這樣的進程,可以想象共享的方法可以節(jié)省大量的內(nèi)存。

程序運行之后

程序在加載到內(nèi)存前,代碼區(qū)和全局區(qū)(data和bss)的大小就是固定的,程序運行期間不能改變。然后,運行可執(zhí)行程序,操作系統(tǒng)把物理硬盤程序load(加載)到內(nèi)存,除了根據(jù)可執(zhí)行程序的信息分出代碼區(qū)(text)、數(shù)據(jù)區(qū)(data)和未初始化數(shù)據(jù)區(qū)(bss)之外,還額外增加了棧區(qū)、堆區(qū)。

代碼區(qū)(text segment)

加載的是可執(zhí)行文件代碼段,所有的可執(zhí)行代碼都加載到代碼區(qū),這塊內(nèi)存是不可以在運行期間修改的。

未初始化數(shù)據(jù)區(qū)(BSS)

加載的是可執(zhí)行文件BSS段,位置可以分開亦可以緊靠數(shù)據(jù)段,存儲于數(shù)據(jù)段的數(shù)據(jù)(全局未初始化,靜態(tài)未初始化數(shù)據(jù))的生存周期為整個程序運行過程。

全局初始化數(shù)據(jù)區(qū)/靜態(tài)數(shù)據(jù)區(qū)(data segment)

加載的是可執(zhí)行文件數(shù)據(jù)段,存儲于數(shù)據(jù)段(全局初始化,靜態(tài)初始化數(shù)據(jù),文字常量(只讀))的數(shù)據(jù)的生存周期為整個程序運行過程。

棧區(qū)(stack)

棧是一種先進后出的內(nèi)存結構,由編譯器自動分配釋放,存放函數(shù)的參數(shù)值、返回值、局部變量等。在程序運行過程中實時加載和釋放,因此,局部變量的生存周期為申請到釋放該段棧空間。

堆區(qū)(heap)

堆是一個大容器,它的容量要遠遠大于棧,但沒有棧那樣先進后出的順序。用于動態(tài)內(nèi)存分配。堆在內(nèi)存中位于BSS區(qū)和棧區(qū)之間。一般由程序員分配和釋放,若程序員不釋放,程序結束時由操作系統(tǒng)回收。

變量類型的作用域、生命周期與存儲位置

類型作用域生命周期存儲位置
auto變量一對{}內(nèi)當前函數(shù)棧區(qū)
static局部變量一對{}內(nèi)整個程序運行期初始化在data段,未初始化在BSS段
extern變量整個程序整個程序運行期初始化在data段,未初始化在BSS段
static全局變量當前文件整個程序運行期初始化在data段,未初始化在BSS段
extern函數(shù)整個程序整個程序運行期代碼區(qū)
static函數(shù)當前文件整個程序運行期代碼區(qū)
register變量一對{}內(nèi)當前函數(shù)運行時存儲在CPU寄存器
字符串常量當前文件整個程序運行期data段
本站僅提供存儲服務,所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權內(nèi)容,請點擊舉報
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
C語言程序的內(nèi)存布局
(1)C和C++內(nèi)存模型
C語言編程程序的內(nèi)存如何布局
「粉絲問答10」C語言關鍵字static的使用詳解
一條進程的棧區(qū)、堆區(qū)、數(shù)據(jù)區(qū)和代碼區(qū)在內(nèi)存中的映射
簡述JVM(1)——類加載器和運行時數(shù)據(jù)區(qū)
更多類似文章 >>
生活服務
熱點新聞
分享 收藏 導長圖 關注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服