學習筆記:內存,堆棧,到底爲何物?

轉: https://www.cnblogs.com/5207/p/4267689.html

在網上看到了一篇關於面試的博客文,突然發現自己對於這個博主而言簡直差的是十萬八千里,他提到的許多技術我盡然一個也答不上來。於是就開始反思,還是要抱一抱佛腳。左看右看發現了內存這個面試的萬惡之源。

 

     說實話對於內存這種東西即使是一點也不瞭解的人也能寫出許多的程序,但有一個現實問題就是面試時總是會用這些基礎知識來考面試的人。我曾經出面試題的時候也做過一樣的事情,但是想想自己其實也不懂。最近開始更新自己的簡歷,期望來年能找到一份新的工作,纔想起自己還是那個什麼都不懂的開發人員,還是要面對面試官的考問。

 

話說什麼是內存?

內存是計算機中重要的部件之一,它是與CPU進行溝通的橋樑。計算機中所有程序的運行都是在內存中進行的,因此內存的性能對計算機的影響非常大。內存(Memory)也被稱爲內存儲器,其作用是用於暫時存放CPU中的運算數據,以及與硬盤等外部存儲器交換的數據。只要計算機在運行中,CPU就會把需要運算的數據調到內存中進行運算,當運算完成後CPU再將結果傳送出來,內存的運行也決定了計算機的穩定運行。 內存是由內存芯片、電路板、金手指等部分組成的。

——摘自百度百科

 

看完後簡單無法直視,這和我想了解的東西有什麼關係呢?

我的理解爲:內存是一種存儲器,硬件上來說就是一種可以快速存儲計算機數據,CPU將這些數據取得運算。內存就像一個大數組,可以存放許多數據。

 

     這裏就有一個很重要的問題,CPU和內存儲器都是硬件,誰來負責操作這些硬件呢?這就要說到操作系統了。我們通常用的windows、linux、unix這些操作系統,那麼就很自然的想到了對於內存操作與管理其實還是由操作系統提供了機制,應用程序在這個基礎上再完成相應的內存操作。

 

網上找了找資料,windows和linux的內存管理機制來看,都將內存劃分爲了物理內存和虛擬內存。

  • 物理內存

    物理內存就是系統硬件提供的內存大小,是真正的內存,說土點就是那內存條

 

  • 虛擬內存

    虛擬內存就是爲了滿足物理內存的不足而提出的策略,它是利用磁盤空間虛擬出的一塊邏輯內存,用作虛擬內存的磁盤空間被稱爲交換空間(Swap Space)。然後對於內存的操作需要有一種訪問的方法,既然內存是CPU的暫時存數據的地方,那麼CPU讀取數據時肯定要有方法去讀取吧,這就是要說到-內存地址。

 

考慮到內存資源總是有限的,而對於多任務的操作系統來說,應用程序越多自然佔用的就越多,那如何合理的分配內存資源呢?有兩種劃分方法:分段、分頁。

參考文章:http://blog.csdn.net/qingfeng_happy5/article/details/4322723

 

到這我倒是有了一些簡單的理解:

所有的應用程序都是通過編繹器編繹爲了可執行文件,在這個文件裏會有許多的描述內容和程序指令。當這個應用啓動時,操作系統會創建一個進程,並在這個進程中分配一個地址空間,而後隨着應用的不斷執行和操作系統與CPU的調度會不斷的在虛擬地址和物理地址之間做映射,從而擁有了真實的內存空間,可以輸入指令和數據供CPU執行。

 

再來看看堆棧

堆棧這個名詞不陌生,但對於許多開發人和我一樣只知其名,不知其實。寫這個筆記原因是因爲我沒有理解內存與堆棧爲什麼總會放在一起討論?於是邊看資料邊記錄筆記。

 

在計算機領域,堆棧是一個不容忽視的概念,堆棧是兩種數據結構。堆棧都是一種數據項按序排列的數據結構,只能在一端(稱爲棧頂(top))對數據項進行插入和刪除。在單片機應用中,堆棧是個特殊的存儲區,主要功能是暫時存放數據和地址,通常用來保護斷點和現場。要點:堆,列隊優先,先進先出[1] 。棧,先進後出(First-In/Last-Out)。——摘自百度百科

 

看到這個概念我最大的疑問是,堆棧是兩種數據結構?這就是典型的數據結構沒學好的人的反應,呵呵。沒辦法只能繼續尋找資料學習。於是在學習過程中慢慢的就有些理解。

 

先看看堆棧的一些定義和說明

棧(數據結構):一種先進後出的數據結構。——摘自百度百科

 

    這句話讓我想到一個問題,那就是先進後出的這種數據結構有什麼作用呢?帶着這個疑問就去尋找棧的應用場景,下面這個場景突然讓我些明白了什麼:

    “棧可以用來在函數調用的時候存儲斷點,做遞歸時要用到棧!”

    對呀,當我們的代碼在運行的時候不就可以看到一個“棧”嘛,先把方法壓棧,然後逐個的取出來執行。這樣代碼的效率就高了許多,而且順序不會出錯。

    好了,有了這個理解再看下面的內容:

 

棧(操作系統):由編譯器自動分配釋放 ,存放函數的參數值,局部變量的值等。其操作方式類似於數據結構中的棧。

 

棧的優勢是,存取速度比堆要快,僅次於直接位於CPU中的寄存器。但缺點是,存在棧中的數據大小與生存期必須是確定的,缺乏靈活性。另外,棧數據可以共享,詳見第3點。堆的優勢是可以動態地分配內存大小,生存期也不必事先告訴編譯器,但缺點是,由於要在運行時動態分配內存,存取速度較慢。——摘自百度百科

這裏就說明了棧的優點和缺點,同時也引出了棧與堆的區別。所以可以理解棧這種數據結構就是用於大小和週期明確的高速存取結構。

一般存在棧中的數據都有哪些?比如值類型(特別是基本數據類型)和對象句柄之類。

看了棧對於堆的理解就要好多了,先看看定義:

  • 堆(操作系統): 一般由程序員分配釋放, 若程序員不釋放,程序結束時可能由OS回收,分配方式倒是類似於鏈表。

  • 堆(數據結構):堆可以被看成是一棵樹,如:堆排序。

     ——摘自百度百科

 

堆(英語:heap),是計算機科學中一類特殊的數據結構的統稱。堆通常是一個可以被看做一棵樹的數組對象。在隊列中,調度程序反覆提取隊列中第一個作業並運行,因爲實際情況中某些時間較短的任務將等待很長時間才能結束,或者某些不短小,但具有重要性的作業,同樣應當具有優先權。堆即爲解決此類問題設計的一種數據結構。

    ——摘自維基百科

 

所以堆要靈活的多,分配與釋放都可以按需進行。在棧中也說過堆的優點是靈活,缺點也是因爲靈活存取效率會低一些。

其實就數據結構來說,堆就是一個數組或者鏈表,可以看作是一顆完全二叉樹的存儲結構,他的特點就是先進先出。

 

總結

有了對內存和堆棧的一些基本概念後,再回頭看一下自己的問題,內存和堆棧到底爲何物?

 

我的理解內存是計算機的一個硬件組成部分,是CPU執行指令的數據存儲區,內存就是提供了這一塊存儲空間。想要使用這塊存儲空間就得用到操作系統,由於與硬件打交道的就是操作系統,而操作系統決定了對內存的管理機制。而應用軟件需要對內存進行存取就要用到堆棧,這是兩種數據結構,決定了數據在內存空間裏的存儲結構。

 

應用程序在內存中的存儲結構是由編繹器決定的。這個我的描述可能不準確,下面說一下C++中內存的分區機制可能會比較好理解一些。 

  • 棧,就是那些由編譯器在需要的時候分配,在不需要的時候自動清除的變量的存儲區。裏面的變量通常是局部變量、函數參數等。 

  • 堆,就是那些由new分配的內存塊,他們的釋放編譯器不去管,由我們的應用程序去控制,一般一個new就要對應一個delete。如果程序員沒有釋放掉,那麼在程序結束後,操作系統會自動回收。 

  • 自由存儲區,就是那些由malloc等分配的內存塊,他和堆是十分相似的,不過它是用free來結束自己的生命的。 

  • 全局/靜態存儲區,全局變量和靜態變量被分配到同一塊內存中,在以前的C語言中,全局變量又分爲初始化的和未初始化的,在C++裏面沒有這個區分了,他們共同佔用同一塊內存區。 

  • 常量存儲區,這是一塊比較特殊的存儲區,他們裏面存放的是常量,不允許修改(當然,你要通過非正當手段也可以修改,而且方法很多)

 

 

寫到這感覺還是有許多的疑問,爲什麼內存的管理會使用這些數據結構呢?堆棧之外有沒有更好的辦法來管理?這是否與計算機的發展歷史有關呢

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章