問:程序運行爲何須要內存?


本章知識點主要來自朱有鵬老師視頻課,部分本身添加總結java

什麼是內存?(硬件和邏輯兩個角度)

從硬件角度:內存其實是電腦的一個配件(通常叫內存條)。根據不一樣的硬件實現原理還能夠把內存分紅SRAM和DRAM(DRAM又有好多代,譬如最先的SDRAM,後來的DDR一、DDR2·····、LPDDR)程序員

從邏輯角度:內存是這樣一種東西,它能夠隨機訪問(隨機訪問的意思是隻要給一個地址,就能夠訪問這個內存地址)、而且能夠讀寫(邏輯上固然也能夠限制其爲只讀或者只寫);內存在編程中自然是用來存放變量的(就是由於有了內存,因此C語言才能定義變量,C語言中的一個變量實際就對應內存中的一個單元)。算法

計算機程序運行的目的是什麼?

計算機爲何須要編程?編程已經編了不少年,已經寫了不少程序,爲何還須要另外寫程序?計算機有這個新的程序到底爲了什麼?編程

程序的目的是爲了去運行,程序運行是爲了獲得必定的結果。數組

計算機就是用來計算的,全部的計算機程序其實都是在作計算。計算就是在計算數據。數據結構

因此計算機程序中很重要的部分就是數據。函數

計算機程序 = 代碼 + 數據                計算機程序運行完獲得一個結果,就是說代碼 + 數據 (通過運行後) = 結果性能

從宏觀上來理解,代碼就是動做,就是加工數據的動做;數據就是數字,就是被代碼所加工的東西。spa

那麼能夠得出結論:程序運行的目的不外乎2個:結果、過程操作系統

用函數來類比:

  1. 函數的形參就是待加工的數據(函數內還須要一些臨時數據,就是局部變量),
  2. 函數本體就是代碼,
  3. 函數的返回值就是結果,
  4. 函數體的執行過程就是過程。
int add(int a, int b)

{

return a + b;

}                        // 這個函數的執行就是爲了獲得結果

void add(int a, int b)

{

int c;

c = a + b;

printf("c = %d.\n", c);

}                        // 這個函數的執行重在過程(重在過程當中的printf),返回值不須要

int add(int a, int b)

{

int c;

c = a + b;

printf("c = %d.\n", c);

return c;

}                        // 這個函數又重結果又重過程

計算機程序運行過程

計算機程序的運行過程,其實就是程序中不少個函數相繼運行的過程。程序是由不少個函數組成的,程序的本質就是函數,函數的本質是加工數據的動做。

什麼是代碼?:函數

什麼是數據?:全局變量、局部變量

總結:爲何須要內存呢?

內存是用來存儲可變數據的,數據在程序中表現爲全局變量、局部變量等(在gcc中,其實常量也是存儲在內存中的,對於大部分單片機中,常量是存儲在flash中的,也就是在代碼段),對咱們寫程序來講很是重要,對程序運行更是本質相關。

因此內存對程序來講幾乎是本質需求。越簡單的程序須要越少的內存,而越龐大越複雜的程序須要更多的內存。內存管理是咱們寫程序時很重要的話題。咱們之前學過的瞭解過的不少編程的關鍵其實都是爲了內存,譬如說數據結構(數據結構是研究數據如何組織的,數據是放在內存中的)和算法(算法是爲了用更優秀更有效的方法來加工數據,既然跟數據有關就離不開內存)。

 

 

深刻思考:如何管理內存(無OS時,有OS時)

對於計算機來講,內存容量越大則性能越大,因此你們都但願本身的電腦內存更大。咱們寫程序時如何管理內存就成了很大的問題。若是管理不善,可能會形成程序運行消耗過多的內存,這樣早晚內存都被你這個程序吃光了,當沒有內存可用時程序就會崩潰。因此內存對程序來講是一種資源,因此管理內存對程序來講是一個重要技術和話題。

先從操做系統角度講:

操做系統掌握全部的硬件內存,由於內存很大,因此操做系統把內存分紅1個1個的頁面(其實就是一塊,通常是4KB),而後以頁面爲單位來管理。頁面內用更細小的方式來以字節爲單位管理。操做系統內存管理的原理很是麻煩、很是複雜、很是不人性化。那麼對咱們這些使用操做系統的人來講,其實不須要了解這些細節。操做系統給咱們提供了內存管理的一些接口,咱們只須要用API便可管理內存。

譬如在C語言中使用 malloc  free 這些接口來管理內存。

當沒有操做系統時:

在沒有操做系統(其實就是裸機程序)中,程序須要直接操做內存,編程者須要本身計算內存的使用和安排。若是編程者不當心把內存用錯了,錯誤結果須要本身承擔。

再從語言角度來說:

不一樣的語言提供了不一樣的操做內存的接口。

  1. 譬如彙編:根本沒有任何內存管理,內存管理全靠程序員本身,彙編中操做內存時直接使用內存地址(譬如0xd0020010),很是麻煩;
  2. 譬如C語言:C語言中編譯器幫咱們管理直接內存地址,咱們都是經過編譯器提供的變量名等來訪問內存的,操做系統下若是須要大塊內存,能夠經過API(malloc free)來訪問系統內存。裸機程序中須要大塊的內存須要本身來定義數組等來解決。
  3. 譬如C++語言:C++語言對內存的使用進一步封裝。咱們能夠用new來建立對象(其實就是爲對象分配內存),而後使用完了用delete來刪除對象(其實就是釋放內存)。因此C++語言對內存的管理比C要高級一些,容易一些。可是C++中內存的管理仍是靠程序員本身來作。若是程序員new了一個對象,可是用完了忘記delete就會形成這個對象佔用的內存不能釋放,這就是內存泄漏。
  4. Java/C#等語言:這些語言不直接操做內存,而是經過虛擬機來操做內存。這樣虛擬機做爲咱們程序員的代理,來幫咱們處理內存的釋放工做。若是個人程序申請了內存,使用完成後忘記釋放,則虛擬機會幫我釋放掉這些內存。聽起來彷佛C# java等語言比C/C++有優點,可是其實他這個虛擬機回收內存是須要付出必定代價的,因此說語言沒有好壞,只有適應不適應。當咱們程序對性能很是在意的時候(譬如操做系統內核)就會用C/C++語言;當咱們對開發程序的速度很是在意的時候,就會用Java/C#等語言。
相關文章
相關標籤/搜索