內存在程序方面的一些技術知識

對內存的思考
服務器君一共花費了218.983 ms進行了6次數據庫查詢,努力地為您提供了這個頁面。
試試閱讀模式?希望聽取您的建議

今天,計算機系統結構的真正挑戰不在于內存的容量,而是內存的速度。如果你的軟件實際上受到磁盤和內存的等待時間(訪問時間)的限制,那么就是再好的芯片也無濟于事。在內存和cpu之間存在著一道很深的鴻溝,而且是越來越深。在過去,每隔一兩年,cpu的處理速度就會提升一倍,在相同的時間內,內存的容量倒是擴大了一倍,但它的訪問時間提升卻沒有那么明顯。

所以我的理解是:內存主要受限于容量和速度。容量問題除了集成工藝的發展擴大物理內存容量,還可用用虛擬內存的辦法解決。訪問速度則可通過Cache技術的發展和程序設計的優化。

Intel 80x86內存模型及工作原理

80x86內存模型的基本形式是段。它是一塊64kb的內存區域,有一個段寄存器所指向。內存地址的形成過程是:取得段寄存器的值,向左移動4位(相當于乘上16)然后加上偏移地址的值。注意,不同的段地址加上偏移地址可能指向同一個內存地址。

MS-DOS 640k的限制由來:在MS-DOS下運行的應用程序都有一個嚴格的內存限制,就是可用內存只有640KB。這個限制源于Intel 8086這個最初的DOS機器的最大地址返回。8086支持20位的地址,總共是1M的內存。之所以可用內存只有640KB是因為某些段必須保留供系統使用。如:F0000到FFFF 64KB,永久性的ROM區域BIOS、診斷信息等,D0000到EFFF 128KB,用于ROM存儲區域。后面的就不一一列舉。

虛擬內存

和MS-DOS一樣,讓程序受限于機器的物理內存數量是相當不方便的。很早的時候,就有了虛擬內存的概念。它的基本思路是用廉價但緩慢的磁盤來擴充內存。在任一時刻,程序實際需要使用的虛擬內存區段的內容就被載入到實際的物理內存中。當物理內存中的數據有一段時間未被使用,就可能被轉移到硬盤中,節省下來的空間用于載入其他數據。現在的很多計算機系統都使用了虛擬內存的技術。

虛擬內存應用例子:Sun OS中每個程序都運行于32位的地址空間中,每個程序都以為自己有對整個地址空間的訪問權,這正是通過虛擬內存實現的。所有進程共享機器的物理內存,當內存用完時就用磁盤保存數據。在運行時,數據在磁盤和內存之間來回移動,內存管理器把虛擬地址翻譯為物理內存地址,并讓一個進程始終運行于真正的物理內存中。這些都是由操作系統完成,應用程序員只看到虛地址,而不知道具體的切換情況。

虛擬內存通過“頁”的形式組織。也就是操作系統在磁盤和內存之間來回移動進行保護的單位,一般為級K字節。

交換區:從潛在的可能性上說,以進程有關的所有內存都將被系統調用,但是如果該進程不會馬上運行(可能由于優先級等原因或者是處于睡眠狀態),操作系統可能暫時取回給它分配的內存,把該進程相關的信息備份到磁盤上,這樣這個進程就被換出。在磁盤中有一個特殊的交換區用于保存從內存中換出的進程。交換區的大小一般是內存的幾倍。

進程只能操作位于物理內存中的頁面。當一個進程引用一個不存在物理內存中的頁面時,MMU就會產生一個錯誤。內核對此作出反應,并判斷是否有效,無效,內核向進程發出一個“Segmentation violation(段違規)”的信號。如果有效,內核從磁盤中取回該頁,換入到內存中。一旦頁面進入內存,進程便被解鎖,可以重新運行。進程并不知道它曾因為頁面換入時間等待了一會。

Cache存儲器:首先,Cache存儲器是對多層存儲概念的擴展,可以認為Cache是為解決內存和cpu數據交換速度過慢而產出的。

它的特點是容量小,價格高,速度快,它位于內存和cpu之間,有兩種組織方式,有的是位于cpu一側,有的則是位于內存一側。

catch的操作速度和系統周期時間相同,所以一個50MHz的處理器,他的cache的存取周期為20ns,典型情況下,內存的速度僅為cache 的四分之一!速度確實很客觀哈~

簡答的介紹一下cache的工作原理:cache有一個地址列表及他們的內容,隨著處理器不斷引用新的內存地址,地址列表的內容也一直在變化中。當cpu要從內存中取出數據時,先看地址是否存在于cahe地址列表中,如果存在直接讀取,不存在則從內存中讀取。內存中讀取數據以行為單位,在讀取的同時也裝入cache中。

內存泄漏

有些程序并不需要管理他們動態內存的使用,當需要內存時,他們簡單的通過分配內存獲得,而不必擔心如何回收它。當然,如果有回收機制的語言也不必擔心如何釋放分配的內存。

對于需要管理動態內存分配和回收的情況,比如c語言通常不適用垃圾回器(自動回收不用的內存塊)那么這些程序在釋放和分配內存時,就需要認真對待。

堆經常會出現兩種類型的問題:釋放或改寫仍在使用的內存(稱為內存損壞),未釋放不在使用的內存(稱為內存泄漏)。

這是最難被調試發現的問題之一。如果每次已分配的內存塊不再使用了卻不是放,進程就會分配越來越多的內存,導致可用內存越來越少。

避免內存泄漏:每次分配內存時,注意在不用的時候釋放內存。如果釋放和先前分配的不對應,那很可能就會造成內存泄漏!

如果是c語言,一個更簡單的辦法就是用alloca函數分配內存,當離開調用alloca函數時,他分配的內存就會被自動釋放。顯然,這不適用于那些創建比函數身命周期長的變量的函數。有些熱不贊成使用alloca,因為它不并是一種可移植的方法。如果處理器在硬件上不支持堆棧,alloca()就很難高效的實現。

如何檢測內存泄漏:

  1. 如果是unix或者linux,首先用swap命令觀察還有多少可用的交換空間。在短時間內連續鍵入該命令兩三下次,看可用的交換區是否在減少。還可以使用其它的一些如netstat、vmstat的工具。如果發現不斷有內存分配且從不釋放,就可能出現內存泄漏。
  2. 確定可以進程:用ps-lu命令來顯示所有進程的大小。重復這個命令,如果一個進程看上去不斷增長而從不縮小,那么基本可以確定發生泄漏的進程了。

本文地址:http://www.zqhthc.tw/librarys/veda/detail/546,歡迎訪問原出處。

不打個分嗎?

轉載隨意,但請帶上本文地址:

http://www.zqhthc.tw/librarys/veda/detail/546

如果你認為這篇文章值得更多人閱讀,歡迎使用下面的分享功能。
小提示:您可以按快捷鍵 Ctrl + D,或點此 加入收藏

大家都在看

閱讀一百本計算機著作吧,少年

很多人覺得自己技術進步很慢,學習效率低,我覺得一個重要原因是看的書少了。多少是多呢?起碼得看3、4、5、6米吧。給個具體的數量,那就100本書吧。很多人知識結構不好而且不系統,因為在特定領域有一個足夠量的知識量+足夠良好的知識結構,系統化以后就足以應對大量未曾遇到過的問題。

奉勸自學者:構建特定領域的知識結構體系的路徑中再也沒有比學習該專業的專業課程更好的了。如果我的知識結構體系足以囊括面試官的大部分甚至吞并他的知識結構體系的話,讀到他言語中的一個詞我們就已經知道他要表達什么,我們可以讓他坐“上位”畢竟他是面試官,但是在知識結構體系以及心理上我們就居高臨下。

所以,閱讀一百本計算機著作吧,少年!

《Python學習手冊(第4版)》 魯特茲(Mark Lutz) (作者), 李軍 (譯者), 劉紅偉 (譯者), 等 (譯者)

《Python學習手冊(第4版)》學習Python的主要內建對象類型:數字、列表和字典。使用Python語句創建和處理對象,并且學習Python的通用語法模型。使用函數構造和重用代碼,函數是Python的基本過程工具。學習Python模塊:封裝語句、函數以及其他工具,以便構建較大的組件。學習Python的面向對象編程工具,用于組織程序代碼。學習異常處理模型,以及用于編寫較大程序的開發工具。了解高級Python工具,如裝飾器、描述器、元類和Unicode處理等。

更多計算機寶庫...

英超直播吻球网