perl学习之:编译、执行与内存关系(转)
1、所謂在編譯期間分配空間指的是靜態分配空間(相對于用new動態申請空間),如全局變量或靜態變量(包括一些復雜類型的
常量),它們所需要的空間大小可以明確計算出來,并且不會再改變,因此它們可以直接存放在可執行文件的特定的節里(而且
包含初始化的值),程序運行時也是直接將這個節加載到特定的段中,不必在程序運行期間用額外的代碼來產生這些變量。
其實在運行期間再看“變量”這個概念就不再具備編譯期間那么多的屬性了(諸如名稱,類型,作用域,生存期等等),對應的
只是一塊內存(只有首址和大小), 所以在運行期間動態申請的空間,是需要額外的代碼維護,以確保不同變量不會混用內存。
比如寫new表示有一塊內存已經被占用了,其它變量就不能再用它了; 寫delete表示這塊內存自由了,可以被其它變量使用了。
(通常我們都是通過變量來使用內存的,就編碼而言變量是給內存塊起了個名字,用以區分彼此)
內存申請和釋放時機很重要,過早會丟失數據,過遲會耗費內存。特定情況下編譯器可以幫我們完成這項復雜的工作(增加額外
的代碼維護內存空間,實現申請和釋放)。從這個意義上講,局部自動變量也是由編譯器負責分配空間的。進一步講,內存管理
用到了我們常常掛在嘴邊的堆和棧這兩種數據結構。
最后對于“編譯器分配空間”這種不嚴謹的說法,你可以理解成編譯期間它為你規劃好了這些變量的內存使用方案,這個方案寫
到可執行文件里面了(該文件中包含若干并非出自你大腦衍生的代碼),直到程序運行時才真正拿出來執行。
2、編譯其實只是一個掃描過程,進行詞法語法檢查,代碼優化而已。我想你說的“編譯時分配內存”是指“編譯時賦初值”,它只是形成一個文本,檢查無錯誤,并沒有分配內存空間。
當你運行時,系統才把程序導入內存。一個進程(即運行中的程序)在主要包括以下五個分區:
棧區、堆區、全局數據區/靜態區、代碼區、常量區?
- 棧區用來存放局部數據或者是函數的參數,函數的返回值之類的變量(其中還有返回到調用函數下一條指令的地址)
- 堆區用來存放程序中動態申請內存的變量
- 全局變量/靜態區用來存放程序中的全局變量或者是靜態變量,因為它們的大小是確定的,在編譯期間就已經進行靜態空間的分配,而且不會改變,這樣會提高程序對這些數據的訪問速度
- 代碼區(code)用來存放編譯后的二進制代碼
- 常量區用來存放我們聲明的常量(const類型)
代碼(編譯后的二進制代碼)放在code區,代碼中生成的各種變量、常量按不同類型分別存放在其它四個區。系統依照代碼順序
執行,然后依照代碼方案改變或調用數據,這就是一個程序的運行過程。
3、
編譯時分配內存
---------------
編譯時是不分配內存的。此時只是根據聲明時的類型進行占位,到以后程序執行時分配內存才會正確。所以聲明是給編譯器看的
,聰明的編譯器能根據聲明幫你識別錯誤。
運行時分配內存
---------------
這是對的,運行時程序是必須調到“內存”的。因為CPU(其中有多個寄存器)只與內存打交道的。程序在進入實際內存之前要首
先分配物理內存。
編譯過程
---------------
當執行這個EXE文件以后,此程序就被加載到內存中,成為進程。此時一開始程序會初始化一些全局對象,然后找到入口函數
,就開始按程序的執行語句開始執行。此時需要的內存只能在程序的堆上進行動態增加/釋放了。
轉載于:https://www.cnblogs.com/chip/p/4289605.html
總結
以上是生活随笔為你收集整理的perl学习之:编译、执行与内存关系(转)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: FL的萌新之路,开始了!
- 下一篇: 数学中各种矩阵收集(转至其他博主)