導航:首頁 > 編程系統 > linux性能瓶頸

linux性能瓶頸

發布時間:2023-02-13 11:28:45

『壹』 linux操作系統的發展前景如何它有什麼優勢

其實這種問題主要網路一下就行了。我找了兩篇,讀了一下覺得人家說得很好。

linux的發展
近來看一篇「hacking是藝術還是科學」的文章,由此產生了一系列的聯想。由藝術聯繫到文化是再自然不過的事,人類的歷史既是科技的發展史,也是藝術的發展史。藝術(廣義上包括文學)和科技構成了文化。而當今似乎科技被從文化中分離開來,於是我們不得不重談文化。因為同商業主導的其他產物不同, Linux更是一種文化的象徵。
第一在linux的媒體上看到馬克思的頭像覺得很可笑,但是思索一番後方才醒悟:資訊難道不是一種生產資料嗎?開源與私有,恰恰就是資訊的分配方式的區別。
件同貨幣聯系起來時,資訊的圈地運動正式開始。並在幾年的你爭我奪中拼殺下來。同社會的發展不同的是,軟體業是直接從「原始的共產」跳向「資本」形式的。以貨幣來交換軟體的確在一定的時期對經濟起到很大的促進的作用。但是卻限制了更多的人生產形式更加多樣化的軟體的能力。長遠角度看這是對發展不利的。於是,共有的分配資訊的方式又被一些人重新重視起來。
這種共有資訊的復甦代表這軟體的文藝復興,也就是文化的復興。開源的意義在於,首先是傳播文化,文化產生軟體。如同藝術中很難找到兩部及其相似油畫一樣,社區中很難找到兩部概念過分接近的軟體。這就是開源社區的精神:知識的高度分享,而且高效的利用,最大限度地避免重復浪費。
初期的開源作者也是理想主義者。同早期的無產者一樣,資訊無產者也是理想主義者。理想主義者感染理想主義者,卻拒絕了更多的實用主義者。一定程度上限制的自身的發展。Eric不是理想主義者,所以當他提出開源作為商業模式時,就同人們第一次聽到中國改革開發一樣!事實證明這種決定是正確的!不同的文化中都有優秀特點、優秀的人。優秀的特點借鑒過來,優秀的人吸引過來,文化群體才能由此而壯大!相反,如果我們不能同其他群體的人和睦相處,對這些人進行人身攻擊和冷言嘲諷,認為linux具有高高在上的優越感。這樣非但不能為我們的群體吸引更多的優秀的支持者。也會使其他的群體產生我們本身的群體數字偏低的印象。

Linux同Windows,文化於市場的差別
我個人認為Linux同Windows不存在討論技術的差別的意義。因為很難指定出一種適普的標准來衡量它們。但是,他們身上一些特點的卻十分明顯地分別體現出文化與市場的特徵:

分發機制

最初的linux用戶真正的是from scratch。因為發布的內核同各類的GNU軟體分不在網路的各個角落。包括為了擁有圖形界面,也要在安裝X之後編譯大量的其他軟體。而為上市而開發的 windows卻是一個超大的軟體包。因為要做到真正的「友好」,不可能讓用戶用一個月的時間來安裝應用軟體,何況入門用戶還根本無法安裝應用軟體。大家記得身邊有些人是花多長時間理解「添加刪除程序的」。
同樣,普及或者商業化必然就要走集成的道路。從最早期的紅帽子,到GNOME,KDE的問世。社區已經盡力提供了各種手段來促進Linux的市場和普及。當然也越來越類似windows,一些操作方式開始向windows兼容。而近年來國內一個Linux廠商的發行本將這種趨勢推至極限,因此相當的受國際社區的反感。

第三方軟體的管理機制

除了歷史遺留問題和向DOS兼容問題。一些Windows的機制我認為不是一個Linux愛好者們所說的缺陷,而是最大限度的面向市場的結果。下面一一舉例說明:
1)目錄的管理方式和注冊表
windows使用相互獨立的第三方軟體目錄組織方式,並且盡量避免不必要的軟體安裝到系統的目錄下。這樣的組織正是市場最大化的結果。由於商業競爭,封閉源代碼的原因。每個廠商在開發軟體時的命名相互之間經常產生沖突,即使是共享庫之間也互不兼容。唯一的辦法就是放在各自的目錄下。但這樣運行程序的時候的路徑又成了問題,於是目錄的方式必然導致了注冊表的誕生,讓程序員通過注冊表解決路徑問題。同樣也捎帶解決了配置文件的路徑問題,可以盡量少的避免使用配置文件了。
linux向來就沒有第三方的軟體的概念,從unix被發明時起就是這樣。所有的軟體都裝在標準的幾個目錄下,而信息的高度共享是避免沖突的最有效的方式。這種方式可以把腳本的作用發揮到極限,以我個人的觀點:同樣是腳本,對windows和linux的意義有本質的區別。二者區別的根本原因就是目錄的組織。而由於是信息的透明,如存在操作系統對第三方軟體的保密問題,也不存在沖突問題。但是,也註定起不到windows那樣的商業效果。
2)病毒的肆虐,歷史遺留和市場綜合作用的結果
我個人不同意*nix上鮮有病毒是因為用戶數量過少的說法。我認為windows上的病毒肆虐主要有兩個因素:
首先是歷史遺留問題。unix從一開始就是多用戶多人的操作系統,所以首先從一開始就要為許可權等安全問題考慮,並且制定了一套在相當長一段時期行之有效的安全機制。而DOS的目標是在一個性能十分有限的微型計算機上提供一個簡單的系統。這是十分合理的!但是卻為後來的系統設計安全機制帶來了兼容的問題。這是作為一個廠商和封閉源代碼的軟體必須考慮的。也導致了早期windows的16位代碼等等。而且這些問題一直延伸到最新的操作系統和文件系統。最新的 NT內核的系統也從unix身上借鑒了一些特性。但受兼容性的束縛很多問題的解決幾乎是不可能的。很多問題不是微軟造成的,包括第三方的廠商甚至是用戶本身造成的。
具體來說現在裝機用戶很多都是用在零售商那裡的ghost的系統。不論多大的硬碟會被等分4-6個分區。而且全都FAT32的文件系統。而且大多數用戶在重新安裝系統時也不會將系統分區改成NTFS,更不會改動其他的分區。這樣就帶來了更多的病毒隱患,而很多病毒是在機制上早就解決了的。
另外,幾乎全部的XP的桌面用戶每天都在以超級用戶身份使用系統。一種原因是因為XP上默認的用戶許可權就是超級用戶。而令一個原因也迫使用戶不得不每天使用超級用戶,應該是廠商的水平和遺留問題。絕大部分的應用軟體,尤其是國產軟體在其他低許可權的用戶的登錄上是無法正常使用的。通常情況廠商限於水平無法同系統的安全機制達成一致。比如國產殺毒軟體很多,但注冊系統服務的不多。我所見的同windows的安全機制結合的最好的恐怕是諾頓的軟體。注冊系統服務。而且用戶數據保存在用戶的主目錄下(Do*****ents and Settings下的用戶名的文件夾下)等等措施保證了無論以任何身份運行登錄,殺毒軟體都能夠正常的起作用。而大多數的國產軟體以一個管理員的身份安裝之後,在另一個管理員的桌面和菜單上都找不到圖標!一些軟體將數據包存在安裝目錄下,這本來就是單用戶系統下的習慣。比如QQ,默認情況下低許可權用戶根本沒辦法使用正常,要設置Tencent文件夾的許可權才行,這樣這個文件夾又成了對所有用戶可寫的了!如果把用戶數據保存到Do*****ents and Settings下,每個用戶相互獨立有什麼困難?恐怕是照顧一些使用98的用戶或者自己的程序員吧!大家都使用超級用戶,好啊!病毒什麼的都懶得研究什麼許可權提升了!想改什麼就改什麼!記得一個同學叫我去殺毒!我一看現在的病毒真的是簡單了!直接把文件名一改省得感染文件了。然後在 autorun.ini里加上一條就可以保證運行傳播了!而這個病毒據說還是大名鼎鼎的流行!如果大家平時不用管理員的話,這個病毒恐怕根本沒有傳播的可能!所以IE和firefox都用漏洞,但IE可能就回感染系統,而firefox只能感染用戶。這不是系統的問題,只是用戶自身的問題,當然系統要對用戶養成這些毛病負責!
然後就是市場問題,記得*nix出現病毒或者蠕蟲的話。都是有人發布補丁的。蠕蟲這里不談,因為蠕蟲主要是通過服務傳播的,是服務的缺陷。*nix的每個病毒都象徵這一些機制的問題。於是這些機制一旦修正,所有同類的病毒就不會感染了!於是*nix下的殺毒軟體其實是查殺通過samba monnt的目錄上的windows病毒。但作為windows來講,病毒意味著意想不到的市場!而且這么大的經濟效益也能推動全球的經濟增長!用三個代表判斷也是對人民有利的!
3)IDE
我覺得不同意那些對linux下IDE環境的看法。對優秀的程序員來說,整個Linux就是一個IDE,只不過你同他打交道不是用滑鼠點擊,而是用命令和腳本程序。由於上面談到的目錄的優勢,所有的程序都被組織在一起了!其實是一個傳統IDE的不同功能模塊被在不同的幾個程序中實現了,而且合作起來也更加靈活。而這個IDE除了軟體開發還可辦公和娛樂,集成度顯然更高了!有些人甚至網頁之類的都用腳本來處理寫好的帶標記的文本來發行出去。如果說哪種IDE 更加高效的話,理所當然是這種全自動的方式。

Linux在中國,文化和市場

Linux在中國達到今天的規模完全是市場的作用,說實話教育界起到的微弱的作用讓人十分遺憾。人們透過媒體知道了Linux。不管是否處於宣傳者的本意,linux被扣上了「高深」的光環。「CLI」、「用於伺服器」之類的說法嚇走了一批觀望者,也有吸引了一批喜歡挑戰難度的人眼球。應該說這批人都是優秀的人,但不是全部優秀的人都會對Linux產生興趣。因為宣傳中透露出linux一個特點「不成熟」,「不成熟」意味著沒錢途。
人才的缺乏卻給了勇敢的人「錢途」。他們成了優秀的程序員或者系統管理員,開發了很多優秀的軟體。然而絕大多數為了公司,卻很少為了社區。也有人成為了商業unix系統的管理員。
客觀地講,Linux的文化向國內的傳播相對於市場向國內擴展是十分緩慢的。大陸的Linux廠商和產品比港台多,但是幾乎所有擁有中文化信息的國際開源社區中香港和台灣的參與者都比大陸的活躍,你可以看到支持GB的軟體遠少於BIG5,zh_CN的文檔遠少於zh_TW。成熟的程序員們也不願意些入門的文檔。只有少數人以論壇版主的身份整理文章和搜集資料。文檔的缺乏和語言的隔閡使我們遲遲不能真正的了解到國際社區的文化,更談不上回報社區。媒體上的報道全部以市場為中心……國際社區疑惑了,中國人到底對linux感不感興趣?
關於市場格局的報道太多,我手頭沒數據沒辦法評論。但是與一些報道不符的是,作為一種特殊的商業產品。linux的市場不能單單的拿訂單來衡量,也不能看政府的笑臉分析。在中國RedHat/Fedora的用戶數量占絕對的優勢(程序員背景的用戶較偏向debian和gentoo),只要到幾個中文的 Linux社區看看就知道了。這些目前的用戶將來一旦成了技術人員就是潛在的訂單。這種規模的用戶份額除了和國際市場的規模之外,主要和RedHat苦心經營的社區效應有關,通過fedora社區RedHat的開發人員幾乎同用戶和貢獻者們無縫地交流。相比之下急於開拓市場的紅旗卻沒有意識到這一點。多數用戶對紅旗的了解少得可憐。已經成為制約公司發展的瓶頸。以中國目前的現狀來看,社區的意義不僅在於潛在的市場和用戶,也是為公司自己培養人才。
個人雖然不贊成製作和發行帶有民族氣質性的linux發行版本,但還是希望國內誕生越來越多的基於社區發展起來的發行版本的開發團隊以及其他的開發人員社區。同市場的曇花一現相比社區的發展壯大才跟家的持久和有力。

文化角度的Linux未來展望

觀望這幾年國際linux和其他開源系統的發展。社區的發展遠遠比市場的發展要明顯得多,從文化的傳播的角度看來這是一種巨大的成功。為了保持和發揚這種成果,我們需要為社區吸引更多的用戶和開發人員。讓更多的軟體使用開源的許可協議。
在國內linux的用戶可能會從學校開始逐漸的擴大。但在市場上可能還是體現在更多的商業的Unix的優秀人才的增多。這些人才普遍是在linux社區成長起來的。另外國內的用戶會對國際的開源社區有更多的了解。更多的資料被翻譯成簡體中文。最重要的是國際社區中會出現更多的中國人。國內也會出現一些較為成熟、具有一定規模的開發社區。
Linux程序員和用戶身上的優秀的品質和文化氣息會吸引更多的人渴望了解和使用Linux面對他們社區的成員們應該比以前有更好的姿態去面對這些未來的同伴們。開源軟體除了影響本身的開發人員和用戶以外,也會對window下的程序員產生更大的影響,進而促進windows下的開發人員提高自己的水平,能夠編寫出同系統設計風格一致的軟體。在改進安全性的同時也意識到開源對於他們的重大意義。
在同商業模式結合方面我並沒有權力去做什麼展望。就想去預測股市一樣。Linux對未來的意義在於:通過文化的影響力讓一些被作為商品的技術盡快的被普及和貶值,以此來消除知識傳播的壁壘和刺激更新的技術的不斷更新。而對最新的技術開放源代碼也可以讓這些技術得到最快速的推廣和實現。

附:如何學習linux?
做為中國人的特殊情況,學習linux對中國人來說要做的事情相對多了一些:
1、以linux為榮耀,以幫助他人了解和學習linux為己任。
2、堅持訪問英文網站,尤其是一些大師的個人主頁。堅持閱讀英文文檔,並盡量翻譯你讀過的文檔發表到國內的社區上供他人閱讀和整理
3、了解unix的歷史,linux的歷史和hacker的歷史及文化。
4、盡可能聯系所以可以聯繫到Linux的愛好者,盡可能多的了解你能接觸到的最了解linux的人對linux的看法。並於自己的觀點相比較。
5、空閑時思索為什麼自己喜歡linux,別人為什麼喜歡linux。為什麼你們喜歡的理由不同?
6、閱讀各類的開源許可協議和商業的用戶許可協議。對比他們各有哪些問題和優勢。
以上使你了解開源文化,是作為一個合格的linux社區成員的前提。
7、安裝一個linux的發行版本。
8、盡你最大的能力把你的學習、娛樂或者工作的環境轉移到linux上來。盡量避免尋找linux功能類似的軟體,而是尋找linux下解決同樣問題的通用的方法。並且對比同windows下的解決方法哪種更加優越。
9、學會SHELL編程。SHELL幾乎可以作為一個入門語言來學習。最低的要求是能夠看懂你自己的版本的linux的配置腳本。理解為什麼一些帖子中里提到的配置方法回起作用,並了解你的發行版本怎樣從每個配置文件中把設置用環境變數的形式讀取並讓他生效的。
10、學會安裝以各種方式發行的程序,並且讓他們的安裝同你系統的慣例一致。熟悉X windows的運作方式。熟悉你的發行版本的安全機制,並且學會定製他們按你的需求工作。
如果僅僅是作為用戶並且部分體會unix的哲學,上面的幾點就足夠了。個人認為這幾點足夠成長為一個合格的Linux用戶了。甚至只要再稍稍的擴充就可以製作自己的發行版本了!而對於不同的用戶群體,比如辦公用戶或者科研人員等。第8條意味著不同的標准。
11、選擇一門或幾門語言社區常用的編程語言。
12、搜集社區或者hackers推薦的圖書或資料、網站、新聞組等。
13、選擇一個較小的用你當前學習的語言開發的開源項目。閱讀他的代碼,並且對比他的代碼和你形象的編寫方式是否相同?哪種更加優越?
14、嘗試按照TODO中的要求為這個軟體編寫代碼,並且同他的作者聯系。學習autoconf和automake等工具的用法。
15、你也可以不參與項目的開發,但仍然能從代碼閱讀中獲益。如果項目是一種你沒有接觸到的技術或者標準的實現,那麼搜集資料讀懂它!
16、學會使用linux下的調試工具,如果軟體還不太穩定,可以幫助找出BUG並且改正。並且學會製作patch發給作者。
17、如果曾是windows的程序員,嘗試把開發環境轉移到linux下來。或者開始在windows的開發工作中使用開源的開發工具和SDK。

18、如果是系統管理員,還要學會在linux部署更強的各類的安全方案。但這已經不屬於學習linux的范疇了。
上面介紹了幾條學習的要求,主要強調的是學習的態度。至於具體什麼樣的技術和自己應該在技術層次上的要求,按照上面介紹的方法應該會慢慢的體會到。

linux操作系統的全稱是GNU/Linux,它是由GNU工程和linux內核兩個部分共同組成的一個操作系統,雖然這個系統誕生於1992年,比windows操作系統要晚,但是與windows相比它有很多獨到的優勢。

首先,對於普通用戶而言它有以下幾個優點:

1.極高的穩定性

回顧linux的歷史我們會發現,linux操作系統的架構完全沿襲了UNIX的系統架構,所以先天就具有成熟穩定的特點,在這方面不是另起爐灶的windows系列操作系統可以比擬的。大家都知道,windows系統最為人垢病的缺陷之一就是系統的穩定性差,藍屏死機相信每個windows用戶都親身體驗過。雖然1999年微軟不惜花費巨資打造了win2000這個劃時代的產品,系統的穩定性得到了加強,後續發布的xp和2003更進一步增強了穩定性,但是藍屏死機的問題只是有所緩解而沒能徹底的根治。反觀linux系統,早在上個世紀九十年代,美國motorola公司在選擇電信級的操作系統的時候就選擇了linux系統,它的運行可靠性要求達到99.999%。這個可靠性所代表的含義是每年的計劃外停機時間累計不得超過5分鍾,由此看見 linux系統所具有的穩定性不是win系統可以望其項背的。

2.先天的安全性

可以說一個操作系統的架構就已經預先決定了它的安全性。linux系統在設計的時候就是針對多用戶環境的,所以對系統文件,用戶文件都做了明確的區分,每個文件都有不同的用戶屬性。作為一個普通用戶通常只能讀寫自己的文件,而對一般的系統文件只能讀取而不能改動,一些敏感的系統文件甚至連讀取都是被禁止的。這種設計在根本上保證了系統的安全,即使一個用戶文件出現了問題,也不會泱及整個系統。反觀windows系統,在win2000之前的時代,用戶與用戶之間是沒有這種差別的,幾乎所有的系統用戶都有管理員的許可權,可以任意改動系統文件。即使後來微軟意識到了這個問題,在後續的系統中區分了管理員和普通用戶這兩種用戶,但是在許可權的問題上他還是沒有很好的解決這個問題,管理員能做的,普通用戶還是基本都可以做,比如安裝軟體,修改系統設置,刪除用戶文件。這從而也說明了,為什麼一旦windows的一個普通用戶中了病毒或者木馬,通常會危及整個系統的安全,而在linux世界這樣的情況幾乎沒有出現過的原因。

3.軟體安裝的便利性

對於計算機初級用戶來說,軟體安裝是個很大的問題。在windows平台下,如果你不知道軟體應該安裝通常只要一直用滑鼠點「下一步」就可以完成安裝。在linux平台下,軟體安裝的便利性方面曾一度落後於win,但是apt的出現使得這種局面得到了徹底的改觀,用戶只要告訴安裝程序自己現在需要安裝什麼軟體,安裝程序就會自動去下載這個程序,然後安裝,最後等待用戶開始運行它。從這個意義上將,linux已經超越了win軟體的安裝方式,進一步降低了用戶的參與程度,方便了用戶。

其次,談一下對開發人員來說linux有哪些優勢

1.系統所有組件的源代碼都是自由的

首先需要澄清的就是自由的含義。自由軟體所指的自由不是免費使用,而是指程序的源代碼是開放的,任何人都可以讀,可以修改,唯一的限制就是,修改後的程序必須連同源代碼也一起發布。對於普通用戶而言這一點也許沒什麼用處,但是對於開發人員來說,你們可以通過讀取大量的經典程序的源代碼,迅速提高自己的編碼水平,在需要的時候可以修改源代碼來適應自己的需要,當你主持一個項目的開發時,你可以通過吸收別人改進過的代碼來不斷提高這個項目的質量,當你的程序中存在bug的時候,會被讀取代碼的人迅速發現並提供補丁程序,使你的程序越來越安全。當你進入linux世界的時候你會發現,這里就是程序員的天堂,所有的一切你都可以主宰。而所有這些在linux平台上都是再正常不過的事,但是對於windows用戶來說這些都是不可能的,源代碼就是 windows的生命,任何未經授權的人想讀到它都是不可能的。

2.有效保護學習成果

前面我們講到linux的系統架構源於UNIX,這個架構從1969年誕生至今一直沿用,在可以預見的未來它仍然會使用下去。同時主力的開發語言一直是C語言,編輯器仍然是歷史悠久的vi。雖然現在你可以使用任何一種語言來為linux系統貢獻代碼,但是它們的作用都是輔助性的,C語言作為這個系統的核心語言的地位沒有發生變化。而windows平台則遠遠沒有這么樂觀。編程語言從古老的BASIC到後來的VB,C++到現在的C#,幾年就一換,開發工具更是令人眼花繚亂,讓人無從選擇,無論你選擇了哪種語言哪種開發工具,兩三年後你都不得不學習新工具的使用,新平台的特點,以跟上微軟變幻莫測的腳步。只有過來人才能體會到做windows平台開發的艱辛和無奈。

3.從就業的前景來看

目前做windows平台開發的程序員多如牛毛,沒有研究生級別的學歷和過硬的編碼能力想找到一分待遇優厚的工作已經不可能了。而反觀linux 平台開發,目前國內這方面的開發人員還很少,而linux應用已經在我國開始升溫,廣東省已經率先建立了linux的研發中心,在linux應用方面走在了全國前面。大家現在及時投身於linux平台的學習和開發,必定會為畢業後的求職增加一個有力的籌碼。雖然現在廣告上宣傳的linux程序員月薪1萬以上不能完全相信,但是它必定給我們一個信號,linux程序員在中國是大有前途的。

『貳』 如何簡單的找出linux系統瓶頸

基本流程:
1、使用top查看系統的總體運行情況;

Top的輸出結果那些是很有用的信息呢?我已經全部用紅線框起來了,具體如下:
:load average 這行表示系統最近1分鍾,5分鍾,15分鍾的平均負載。那麼怎樣的負載才是可以接受的呢?有個簡單的辦法,在top命令中,再按『1』鍵,會列出系統使用的cpu的數量,以負載的值不要超過cpu數量最合適。
:Tasks 這行反應的是當前系統的任務狀態,主要看running和zombie進程的數量,一個健康的系統zombie(僵死進程)的數量一定是為0的,否則肯定系統已經出不小的問題了。
:Cpu(s)這行反應當前cpu的工作狀態,us表示用戶進程占整個cpu運行時間的百分比,sy表示系統進程的佔用時間百分比;id表示cpu當前的空閑時間百分比,wa表示等待時間百分比,這幾個概念是最重要的。下面有個實際的列子會再詳細分析。
:Mem這行反應當前系統內存使用狀況
:Swap 這行就是系統交換分區使用狀態,一個性能優越的系統,交換分區使用量一定是為0的,交換分區只是一種應對在系統內存不足時的一種緊急機制,用到交換分區,說明可以考慮增加內存或者裁減現有內存數據大小了。畢竟交換分區就是硬碟,速度和內存差了太多。
2、看硬碟容量,硬碟容量如果爆滿的話,那麼什麼詭異的情況都可能出現,這個已經非常危急了,具體的命令:df;

3、看帶寬;這里如果細分的話就復雜了,比如是否有網路攻擊,封包數量和特徵是否異常等,zabbix是其中的佼佼者,這里我們只要看目前的帶寬有沒有接近網卡的上限,命令: dstat -n;

這台機器是千兆網卡,現在最大才跑到2.7mbyte/s *8 ~ 20mbit/s,遠遠沒到,帶寬這個很少有機會用到網卡峰值的80%左右,但是在業務繁忙的時候,這個也是非常重要的監控對象。
4、一個具體的實例。昨天一個新同學說應用很卡,延遲較大。內存還有很多不使用,就如上面top圖顯示那樣,還有接近3G可以使用的內存。我等錄上去看了看,使用vmstat:

可以看到過段時間就會發現有些進程處於阻塞狀態,原因內是因為cpu處於等待的時間變長了,cpu是空閑的很,等著進程進來運算,而進程遲遲沒有到達,這個肯定就是數據在交換分區了,存取太慢導致的卡和延遲,後來關閉了交換分區,並且整理內存之後,一切就正常了。
一個初步的系統性能診斷按照基本流程就幾步,只是開始接觸linux的同學不知道按照一個流程來操作。所以需要多看多動手。當然現在監控軟體很多,可以監控的性能指標也很多。

『叄』 centos伺服器怎麼內存優化

作為一名Linux系統管理員,最主要的工作是優化系統配置,使應用在系統上以最優的狀態運行,但硬體問題、軟體問題、網路環境等的復雜性和多變性,導致了對系統的優化變得異常復雜,如何定位性能問題出在哪個方面,是性能優化的一大難題。 本文從系統入手,重點講述由於系統軟、硬體配置不當造成的性能問題,並且給出了檢測系統故障和優化性能的一般方法和流程。

一、 系統性能分析的目的

1.1 找到系統性能的瓶頸
系統的性能是指操作系統完成任務的有效性、穩定性和響應速度。Linux系統管理員可能經常會遇到系統不穩定、響應速度慢等問題,例如在Linux上搭建了一個Web服務,經常出現網頁無法打開、打開速度慢等現象。遇到這些問題,就有人會抱怨Linux系統不好,其實這些都是表面現象。操作系統完成一個任務是與系統自身設置、網路拓樸結構、路由設備、路由策略、接入設備、物理線路等多個方面都密切相關的,任何一個環節出現問題,都會影響整個系統的性能。因此,當Linux應用出現問題時,應當從應用程序、操作系統、伺服器硬體、網路環境等方面綜合排查,定位問題出現在哪個部分,然後集中解決。

1.2 提供性能優化方案
查找系統性能瓶頸是個復雜而耗時的過程,需要在應用程序、操作系統、伺服器硬體、網路環境等方面進行查找和定位,影響性能最大的是應用程序和操作系統兩個方面,因為這兩個方面出現的問題不易察覺,隱蔽性很強。而硬體、網路方面出現的問題,一般都能馬上定位。一旦找到了系統性能問題,解決起來就非常迅速和容易,例如發現系統硬體存在問題,如果是物理故障,那麼更換硬體就可以了,如果是硬體性能不能滿足需求,升級硬體就可以了;如果發現是網路問題,比如帶寬不夠、網路不穩定,只需優化和升級網路即可;如果發現是應用程序問題,修改或優化軟體系統即可;而如果是操作系統配置問題,修改系統參數、修改系統配置即可。
可見,只要找到了性能瓶頸,就可以提供性能優化方案,有標准、有目的地進行系統優化。

1.3 使系統硬體和軟體資源的使用達到平衡
Linux操作系統是一個開源產品,也是一個開源軟體的實踐和應用平台,在這個平台下由無數的開源軟體支撐,常見的有Apache、Tomcat、MySQL、PHP等。開源軟體的最大理念是自由、開放,那麼Linux作為一個開源平台,最終要實現的是通過這些開源軟體的支持,以最低廉的成本,達到應用性能的最優化。但是,系統的性能問題並非是孤立的,解決了一個性能瓶頸,可能會出現另一個性能瓶頸,所以說性能優化的最終目的是:在一定范圍內使系統的各項資源使用趨於合理並保持一定的平衡,即系統運行良好的時候恰恰就是系統資源達到了一個平衡狀態的時候。而在操作系統中,任何一項資源的過度使用都會破壞這種平衡狀態,從而導致系統響應緩慢或者負載過高。例如,CPU資源的過度使用會造成系統中出現大量的等待進程,導致應用程序響應緩慢,而進程的大量增加又會導致系統內存資源的增加,當物理內存耗盡時,系統就會使用虛擬內存,而虛擬內存的使用又會造成磁碟I/O的增加並加大CPU的開銷。因此,系統性能的優化就是在硬體、操作系統、應用軟體之間找到一個平衡點。

二、 分析系統性能涉及的人員

2.1 Linux系統管理人員
在做性能優化過程中,系統管理人員承擔著很重要的任務,首先,系統管理人員要了解和掌握操作系統的當前運行狀態,例如系統負載、內存狀態、進程狀態、CPU負荷等信息,這些信息是檢測和判斷系統性能的基礎和依據;其次,系統管理人員還有掌握系統的硬體信息,例如磁碟I/O、CPU型號、內存大小、網卡帶寬等參數信息,然後根據這些信息綜合評估系統資源的使用情況;第三,作為一名系統管理人員,還要掌握應用程序對系統資源的使用情況,更深入的一點就是要了解應用程序的運行效率,例如是否有程序BUG、內存溢出等問題,通過對系統資源的監控,就能發現應用程序是否存在異常,如果確實是應用程序存在問題,需要把問題立刻反映給程序開發人員,進而改進或升級程序。
性能優化本身就是一個復雜和繁瑣的過程,系統管理人員只有了解了系統硬體信息、網路信息、操作系統配置信息和應用程序信息才能有針對性地的展開對伺服器性能優化,這就要求系統管理員有充足的理論知識、豐富的實戰經驗以及縝密分析問題的頭腦。

2.2 系統架構設計人員
系統性能優化涉及的第二類人員就是應用程序的架構設計人員。如果系統管理人員在經過綜合判斷後,發現影響性能的是應用程序的執行效率,那麼程序架構設計人員就要及時介入,深入了解程序運行狀態。首先,系統架構設計人員要跟蹤了解程序的執行效率,如果執行效率存在問題,要找出哪裡出現了問題;其次,如果真的是架構設計出現了問題,那麼就要馬上優化或改進系統架構,設計更好的應用系統架構。

2.3 軟體開發人員
系統性能優化最後一個環節涉及的是程序開發人員,在系統管理員或架構設計人員找到程序或結構瓶頸後,程序開發人員要馬上介入進行相應的程序修改。修改程序要以程序的執行效率為基準,改進程序的邏輯,有針對性地進行代碼優化。例如,系統管理人員在系統中發現有條SQL語句耗費大量的系統資源,抓取這條執行的SQL語句,發現此SQL語句的執行效率太差,是開發人員編寫的代碼執行效率低造成的,這就需要把這個信息反饋給開發人員,開發人員在收到這個問題後,可以有針對性的進行SQL優化,進而實現程序代碼的優化。
從上面這個過程可以看出,系統性能優化一般遵循的流程是:首先系統管理人員查看系統的整體狀況,主要從系統硬體、網路設備、操作系統配置、應用程序架構和程序代碼五個方面進行綜合判斷,如果發現是系統硬體、網路設備或者操作系統配置問題,系統管理員可以根據情況自主解決;如果發現是程序結構問題,就需要提交給程序架構設計人員;如果發現是程序代碼執行問題,就交給開發人員進行代碼優化。這樣就完成了一個系統性能優化的過程。
三、影響Linux性能的各種因素

3.1 系統硬體資源
1.CPU
CPU是操作系統穩定運行的根本,CPU的速度與性能在很大程度上決定了系統整體的性能,因此,CPU數量越多、主頻越高,伺服器性能也就相對越好。但事實並非完全如此。
目前大部分CPU在同一時間內只能運行一個線程,超線程的處理器可以在同一時間運行多個線程,因此,可以利用處理器的超線程特性提高系統性能。在Linux系統下,只有運行SMP內核才能支持超線程,但是,安裝的CPU數量越多,從超線程獲得的性能方面的提高就越少。另外,Linux內核會把多核的處理器當作多個單獨的CPU來識別,例如兩個4核的CPU,在Lnux系統下會被當作8個單核CPU。但是從性能角度來講,兩個4核的CPU和8個單核的CPU並不完全等價,根據權威部門得出的測試結論,前者的整體性能要比後者低25%~30%。
可能出現CPU瓶頸的應用有郵件伺服器、動態Web伺服器等,對於這類應用,要把CPU的配置和性能放在主要位置。
2.內存
內存的大小也是影響Linux性能的一個重要的因素,內存太小,系統進程將被阻塞,應用也將變得緩慢,甚至失去響應;內存太大,導致資源浪費。Linux系統採用了物理內存和虛擬內存兩種方式,虛擬內存雖然可以緩解物理內存的不足,但是佔用過多的虛擬內存,應用程序的性能將明顯下降,要保證應用程序的高性能運行,物理內存一定要足夠大;但是過大的物理內存,會造成內存資源浪費,例如,在一個32位處理器的Linux操作系統上,超過8GB的物理內存都將被浪費。因此,要使用更大的內存,建議安裝64位的操作系統,同時開啟Linux的大內存內核支持。
由於處理器定址范圍的限制,在32位Linux操作系統上,應用程序單個進程最大隻能使用2GB的內存,這樣以來,即使系統有更大的內存,應用程序也無法「享」用,解決的辦法就是使用64位處理器,安裝64位操作系統。在64位操作系統下,可以滿足所有應用程序對內存的使用需求 ,幾乎沒有限制。
可能出現內存性能瓶頸的應用有列印伺服器、資料庫伺服器、靜態Web伺服器等,對於這類應用要把內存大小放在主要位置。
3.磁碟I/O性能
磁碟的I/O性能直接影響應用程序的性能,在一個有頻繁讀寫的應用中,如果磁碟I/O性能得不到滿足,就會導致應用停滯。好在現今的磁碟都採用了很多方法來提高I/O性能,比如常見的磁碟RAID技術。
RAID的英文全稱為:Rendant Array of Independent Disk,即獨立磁碟冗餘陣列,簡稱磁碟陣列。RAID通過將多塊獨立的磁碟(物理硬碟)按不同方式組合起來形成一個磁碟組(邏輯硬碟),從而提供比單個硬碟更高的I/O性能和數據冗餘。
通過RAID技術組成的磁碟組,就相當於一個大硬碟,用戶可以對它進行分區格式化、建立文件系統等操作,跟單個物理硬碟一模一樣,唯一不同的是RAID磁碟組的I/O性能比單個硬碟要高很多,同時在數據的安全性也有很大提升。
根據磁碟組合方式的不同,RAID可以分為RAID0,RAID1、RAID2、RAID3、RAID4、RAID5、RAID6、RAID7、RAID0+1、RAID10等級別,常用的RAID級別有RAID0、RAID1、RAID5、RAID0+1,這里進行簡單介紹。
RAID 0:通過把多塊硬碟粘合成一個容量更大的硬碟組,提高了磁碟的性能和吞吐量。這種方式成本低,要求至少兩個磁碟,但是沒有容錯和數據修復功能,因而只能用在對數據安全性要求不高的環境中。
RAID 1:也就是磁碟鏡像,通過把一個磁碟的數據鏡像到另一個磁碟上,最大限度地保證磁碟數據的可靠性和可修復性,具有很高的數據冗餘能力,但磁碟利用率只有50%,因而,成本最高,多用在保存重要數據的場合。

『肆』 Linux內核參數之arp_ignore和arp_announce

arp_ignore和arp_announce參數都和ARP協議相關,主要用於控制系統返回arp響應和發送arp請求時的動作。這兩個參數很重要,特別是在LVS的DR場景下,它們的配置直接影響到DR轉發是否正常。

首先看一下Linux內核文檔中對於它們的描述:

arp_ignore - INTEGER

Define different modes for sending replies in response to

received ARP requests that resolve local target IP addresses:

0 - (default): reply for any local target IP address, configured

on any interface

1 - reply only if the target IP address is local address

configured on the incoming interface

2 - reply only if the target IP address is local address

configured on the incoming interface and both with the

sender's IP address are part from same subnet on this interface

3 - do not reply for local addresses configured with scope host,

only resolutions for global and link addresses are replied

4-7 - reserved

8 - do not reply for all local addresses

The max value from conf/{all,interface}/arp_ignore is used

when ARP request is received on the {interface}

arp_ignore參數的作用是控制系統在收到外部的arp請求時,是否要返回arp響應。

arp_ignore參數常用的取值主要有0,1,2,3~8較少用到:

0:響應任意網卡上接收到的對本機IP地址的arp請求(包括環回網卡上的地址),而不管該目的IP是否在接收網卡上。

1:只響應目的IP地址為接收網卡上的本地地址的arp請求。

2:只響應目的IP地址為接收網卡上的本地地址的arp請求,並且arp請求的源IP必須和接收網卡同網段。

3:如果ARP請求數據包所請求的IP地址對應的本地地址其作用域(scope)為主機(host),則不回應ARP響應數據包,如果作用域為全局(global)或鏈路(link),則回應ARP響應數據包。

4~7:保留未使用

8:不回應所有的arp請求

sysctl.conf中包含all和eth/lo(具體網卡)的arp_ignore參數,取其中較大的值生效。

arp_announce - INTEGER

Define different restriction levels for announcing the local

source IP address from IP packets in ARP requests sent on

interface:

0 - (default) Use any local address, configured on any interface

1 - Try to avoid local addresses that are not in the target's

subnet for this interface. This mode is useful when target

hosts reachable via this interface require the source IP

address in ARP requests to be part of their logical network

configured on the receiving interface. When we generate the

request we will check all our subnets that include the

target IP and will preserve the source address if it is from

such subnet. If there is no such subnet we select source

address according to the rules for level 2.

2 - Always use the best local address for this target.

In this mode we ignore the source address in the IP packet

and try to select local address that we prefer for talks with

the target host. Such local address is selected by looking

for primary IP addresses on all our subnets on the outgoing

interface that include the target IP address. If no suitable

local address is found we select the first local address

we have on the outgoing interface or on all other interfaces,

with the hope we will receive reply for our request and

even sometimes no matter the source IP address we announce.

The max value from conf/{all,interface}/arp_announce is used.

arp_announce的作用是控制系統在對外發送arp請求時,如何選擇arp請求數據包的源IP地址。(比如系統准備通過網卡發送一個數據包a,這時數據包a的源IP和目的IP一般都是知道的,而根據目的IP查詢路由表,發送網卡也是確定的,故源MAC地址也是知道的,這時就差確定目的MAC地址了。而想要獲取目的IP對應的目的MAC地址,就需要發送arp請求。arp請求的目的IP自然就是想要獲取其MAC地址的IP,而arp請求的源IP是什麼呢? 可能第一反應會以為肯定是數據包a的源IP地址,但是這個也不是一定的,arp請求的源IP是可以選擇的,控制這個地址如何選擇就是arp_announce的作用)

arp_announce參數常用的取值有0,1,2。

0:允許使用任意網卡上的IP地址作為arp請求的源IP,通常就是使用數據包a的源IP。

1:盡量避免使用不屬於該發送網卡子網的本地地址作為發送arp請求的源IP地址。

2:忽略IP數據包的源IP地址,選擇該發送網卡上最合適的本地地址作為arp請求的源IP地址。

sysctl.conf中包含all和eth/lo(具體網卡)的arp_ignore參數,取其中較大的值生效。

(1)當arp_ignore參數配置為0時,eth1網卡上收到目的IP為環回網卡IP的arp請求,但是eth1也會返回arp響應,把自己的mac地址告訴對端。

(2)當arp_ignore參數配置為1時,eth1網卡上收到目的IP為環回網卡IP的arp請求,發現請求的IP不是自己網卡上的IP,不會回arp響應。

(3)當arp_announce參數配置為0時,系統要發送的IP包源地址為eth1的地址,IP包目的地址根據路由表查詢判斷需要從eth2網卡發出,這時會先從eth2網卡發起一個arp請求,用於獲取目的IP地址的MAC地址。該arp請求的源MAC自然是eth2網卡的MAC地址,但是源IP地址會選擇eth1網卡的地址。

(4)當arp_announce參數配置為2時,eth2網卡發起arp請求時,源IP地址會選擇eth2網卡自身的IP地址。

因為DR模式下,每個真實伺服器節點都要在環回網卡上綁定虛擬服務IP。這時候,如果客戶端對於虛擬服務IP的arp請求廣播到了各個真實伺服器節點,如果arp_ignore參數配置為0,則各個真實伺服器節點都會響應該arp請求,此時客戶端就無法正確獲取LVS節點上正確的虛擬服務IP所在網卡的MAC地址。假如某個真實伺服器節點A的網卡eth1響應了該arp請求,客戶端把A節點的eth1網卡的MAC地址誤認為是LVS節點的虛擬服務IP所在網卡的MAC,從而將業務請求消息直接發到了A節點的eth1網卡。這時候雖然因為A節點在環回網卡上也綁定了虛擬服務IP,所以A節點也能正常處理請求,業務暫時不會受到影響。但時此時由於客戶端請求沒有發到LVS的虛擬服務IP上,所以LVS的負載均衡能力沒有生效。造成的後果就是,A節點一直在單節點運行,業務量過大時可能會出現性能瓶頸。

所以DR模式下要求arp_ignore參數要求配置為1。

每個機器或者交換機中都有一張arp表,該表用於存儲對端通信節點IP地址和MAC地址的對應關系。當收到一個未知IP地址的arp請求,就會再本機的arp表中新增對端的IP和MAC記錄;當收到一個已知IP地址(arp表中已有記錄的地址)的arp請求,則會根據arp請求中的源MAC刷新自己的arp表。

如果arp_announce參數配置為0,則網卡在發送arp請求時,可能選擇的源IP地址並不是該網卡自身的IP地址,這時候收到該arp請求的其他節點或者交換機上的arp表中記錄的該網卡IP和MAC的對應關系就不正確,可能會引發一些未知的網路問題,存在安全隱患。

所以DR模式下要求arp_announce參數要求配置為2。

arp_ignore和arp_announce參數分別有all,default,lo,eth1,eth2...等對應不同網卡的具體參數。當all和具體網卡的參數值不一致時,取較大值生效。

一般只需修改all和某個具體網卡的參數即可(取決於你需要修改哪個網卡)。下面以修改lo網卡為例:

net.ipv4.conf.all.arp_ignore=1

net.ipv4.conf.lo.arp_ignore=1

net.ipv4.conf.all.arp_announce=2

net.ipv4.conf.lo.arp_announce=2

sysctl -w net.ipv4.conf.all.arp_ignore=1

sysctl -w net.ipv4.conf.lo.arp_ignore=1

sysctl -w net.ipv4.conf.all.arp_announce=2

sysctl -w net.ipv4.conf.lo.arp_announce=2

echo "1">/proc/sys/net/ipv4/conf/all/arp_ignore

echo "1">/proc/sys/net/ipv4/conf/lo/arp_ignore

echo "2">/proc/sys/net/ipv4/conf/all/arp_announce

echo "2">/proc/sys/net/ipv4/conf/lo/arp_announce

『伍』 linux查看哪個進程佔ioutil

Linux系統出現了性能問題,一般我們可以通過top.iostat,vmstat等命令來查看初步定位問題。其中iostat可以給我們提供豐富的IO狀態數據。 www.jb51.net
iostat結果分析
[kefu@SZ-8 linux]$ iostat -x -k
Linux 2.6.18-128.el5_cyou_1.0 (SZ-8.30) 09/08/2011

avg-cpu: %user %nice %system %iowait %steal %idle
16.58 0.00 2.79 0.46 0.00 80.16

Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await svctm %util
sda 0.06 29.28 0.22 37.14 10.21 265.68 14.77 0.02 0.51 0.15 0.55
sda1 0.00 0.00 0.00 0.00 0.00 0.00 10.79 0.00 2.66 2.43 0.00
sda2 0.01 0.78 0.10 0.36 0.81 4.58 23.51 0.00 1.21 0.84 0.04
sda3 0.03 15.17 0.09 35.39 8.98 202.24 11.91 0.01 0.26 0.12 0.44
sda4 0.00 0.00 0.00 0.00 0.00 0.00 2.00 0.00 33.33 33.33 0.00
sda5 0.01 1.59 0.03 0.51 0.34 8.40 32.20 0.00 1.19 0.58 0.03
sda6 0.00 0.00 0.00 0.12 0.00 0.48 8.18 0.00 5.02 4.53 0.05
sda7 0.00 0.00 0.00 0.00 0.00 0.00 45.00 0.00 5.52 3.04 0.00
sda8 0.00 0.00 0.00 0.00 0.00 0.00 40.88 0.00 7.62 6.03 0.00
sda9 0.00 0.00 0.00 0.00 0.00 0.00 39.71 0.00 7.37 5.83 0.00
sda10 0.00 0.00 0.00 0.00 0.00 0.00 37.57 0.00 5.70 3.54 0.00
sda11 0.00 11.74 0.01 0.76 0.08 49.97 131.48 0.01 10.74 0.57 0.04
sdb 0.01 3.91 20.24 20.21 1262.95 1853.94 154.09 0.52 12.84 1.97 7.95

rrqm/s:每秒進行merge的讀操作數目。即delta(rmerge)/s
wrqm/s:每秒進行merge的寫操作數目。即delta(wmerge)/s
r/s:每秒完成的讀I/O設備次數。即delta(rio)/s
w/s:每秒完成的寫I/0設備次數。即delta(wio)/s
rsec/s:每秒讀扇區數。即delta(rsect)/s
wsec/s:每秒寫扇區數。即delta(wsect)/s
rKB/s:每秒讀K位元組數。是rsec/s的一半,因為每扇區大小為512位元組

wKB/s:每秒寫K位元組數。是wsec/s的一半
avgrq-sz:平均每次設備I/O操作的數據大小(扇區)。即delta(rsect+wsect)/delta(rio+wio)
avgqu-sz:平均I/O隊列長度。即delta(aveq)/s/1000(因為aveq的單位為毫秒)
await:平均每次設備I/O操作的等待時間(毫秒)。即delta(ruse+wuse)/delta(rio+wio)
svctm:平均每次設備I/O操作的服務時間(毫秒)。即delta(use)/delta(rio+wio)
%util:一秒中有百分之多少的時間用於I/O操作,或者說一秒中有多少時間I/O隊列是非空的。即delta(usr)/s/1000(因為use的單位為毫秒)

如果%util接近100%,說明產生的I/O請求太多,I/O系統已經滿負載,該磁碟可能存在瓶頸。

比較重要的參數
%util:一秒中有百分之多少的時間用於I/O操作,或者說一秒中有多少時間I/O隊列是非空的
svctm:平均每次設備I/O操作的服務時間
await:平均每次設備I/O操作的等待時間
avgqu-sz:平均I/O隊列長度

如果%util接近100%,表明I/O請求太多,I/O系統已經滿負荷,磁碟可能存在瓶頸,一般%util大於70%,I/O壓力就比較大,讀取速度有較多的wait。
同時可以結合vmstat查看查看b參數(等待資源的進程數)和wa參數(I/O等待所佔用的CPU時間的百分比,高過30%時I/O壓力高)
await的大小一般取決於服務時間(svctm)以及I/O隊列的長度和I/O請求的發出模式。如果svctm比較接近await,說明I/O幾乎沒有等待時間;如果
await遠大於svctm,說明I/O隊列太長,應用得到的響應時間變慢。

形象的比喻
r/s+w/s類似於交款人的總數
平均隊列長度(avgqu-sz)類似於單位時間里平均排隊的人數
平均服務時間(avctm)類似於收銀員的收款速度
平均等待時間(await)類似於平均每人的等待時間
平均I/O數據(avgrq-sz)類似於平均每人所買的東西
I/O操作率(%util)類似於收款台前有人排隊的時間比例

svctm一般要小於await(因為同時等待的請求的等待時間被重復計算了),svctm的大小一般和磁碟性能有關,CPU/內存的負荷也會對其有影響,請求過多也會
間接導致svctm的增加。await的大小一般取決於服務時間(svctm)以及I/O隊列的長度和I/O請求的發出模式。如果svctm比較接近await,說明I/O幾乎沒有
等待時間;如果await遠大於svctm,說明I/O隊列太長,應用得到的響應時間變慢,如果響應時間超過了用戶可以容許的范圍,這時可以考慮更換更快的磁碟,調
整內核elevator演算法,優化應用,或者升級CPU

隊列長度(avcqu-sz)也可作為衡量系統I/O負荷的指標,但由於avcqu-sz是按照單位時間的平均值,所以不能反映瞬間的I/O洪水。

『陸』 程序裝載進入內存

上一講,我們看到了如何通過鏈接器,把多個文件合並成一個最終可執行文件。在運行這些可執行文件的時候,我們其實是通過一個裝載器,解析 ELF 或者 PE 格式的可執行文件。裝載器會把對應的指令和數據載入到內存裡面來,讓 CPU 去執行。

說起來只是裝載到內存裡面這一句話的事兒,實際上裝載器需要滿足兩個要求。

第一,可執行程序載入後佔用的內存空間應該是連續的 ,執行指令的時候,程序計數器是順序地一條一條指令執行下去。這也就意味著,這一條條指令需要連續地存儲在一起。

第二,我們需要同時載入很多個程序,並且不能讓程序自己規定在內存中載入的位置。 雖然編譯出來的指令里已經有了對應的各種各樣的內存地址,但是實際載入的時候,我們其實沒有辦法確保,這個程序一定載入在哪一段內存地址上。因為我們現在的計算機通常會同時運行很多個程序,可能你想要的內存地址已經被其他載入了的程序佔用了。

要滿足這兩個基本的要求,我們很容易想到一個辦法。那就是我們可以在內存裡面,找到一段連續的內存空間,然後分配給裝載的程序,然後把這段連續的內存空間地址,和整個程序指令里指定的內存地址做一個映射。

我們把指令里用到的內存地址叫作 虛擬內存地址 (Virtual Memory Address),實際在內存硬體裡面的空間地址,我們叫 物理內存地址 (Physical Memory Address)。

程序里有指令和各種內存地址,我們只需要關心虛擬內存地址就行了。對於任何一個程序來說,它看到的都是同樣的內存地址。我們維護一個虛擬內存到物理內存的映射表,這樣實際程序指令執行的時候,會通過虛擬內存地址,找到對應的物理內存地址,然後執行。因為是連續的內存地址空間,所以我們只需要維護映射關系的起始地址和對應的空間大小就可以了。

內存分段

這種找出一段連續的物理內存和虛擬內存地址進行映射的方法,我們叫分段(Segmentation)。這里的段,就是指系統分配出來的那個連續的內存空間。

分段的辦法很好,解決了程序本身不需要關心具體的物理內存地址的問題,但它也有一些不足之處,第一個就是內存碎片(Memory Fragmentation)的問題。

我們來看這樣一個例子。我現在手頭的這台電腦,有 1GB 的內存。我們先啟動一個圖形渲染程序,佔用了 512MB 的內存,接著啟動一個 Chrome 瀏覽器,佔用了 128MB 內存,再啟動一個 Python 程序,佔用了 256MB 內存。這個時候,我們關掉 Chrome,於是空閑內存還有 1024 - 512 - 256 = 256MB。按理來說,我們有足夠的空間再去裝載一個200MB 的程序。但是,這 256MB 的內存空間不是連續的,而是被分成了兩段 128MB 的內存。因此,實際情況是,我們的程序沒辦法載入進來。

當然,這個我們也有辦法解決。解決的辦法叫 內存交換 (Memory Swapping)。

我們可以把 Python 程序佔用的那 256MB 內存寫到硬碟上,然後再從硬碟上讀回來到內存裡面。不過讀回來的時候,我們不再把它載入到原來的位置,而是緊緊跟在那已經被佔用了的 512MB 內存後面。這樣,我們就有了連續的 256MB 內存空間,就可以去載入一個新的200MB 的程序。如果你自己安裝過 Linux 操作系統,你應該遇到過分配一個 swap 硬碟分區的問題。這塊分出來的磁碟空間,其實就是專門給 Linux 操作系統進行內存交換用的。

虛擬內存、分段,再加上內存交換,看起來似乎已經解決了計算機同時裝載運行很多個程序的問題。不過,你千萬不要大意,這三者的組合仍然會遇到一個性能瓶頸。硬碟的訪問速度要比內存慢很多,而每一次內存交換,我們都需要把一大段連續的內存數據寫到硬碟上。所以,如果內存交換的時候,交換的是一個很占內存空間的程序,這樣整個機器都會顯得卡頓。

內存分頁

既然問題出在內存碎片和內存交換的空間太大上,那麼解決問題的辦法就是,少出現一些內存碎片。另外,當需要進行內存交換的時候,讓需要交換寫入或者從磁碟裝載的數據更少一點,這樣就可以解決這個問題。這個辦法,在現在計算機的內存管理裡面,就叫作 內存分頁 (Paging)。

和分段這樣分配一整段連續的空間給到程序相比,分頁是把整個物理內存空間切成一段段固定尺寸的大小 。而對應的程序所需要佔用的虛擬內存空間,也會同樣切成一段段固定尺寸的大小。這樣一個連續並且尺寸固定的內存空間,我們叫頁(Page)。從虛擬內存到物理內存的映射,不再是拿整段連續的內存的物理地址,而是按照一個一個頁來的。頁的尺寸一般遠遠小於整個程序的大小。在 Linux 下,我們通常只設置成 4KB。你可以通過命令看看你手頭的 Linux 系統設置的頁的大小。

getconf PAGE_SIZE

由於內存空間都是預先劃分好的,也就沒有了不能使用的碎片,而只有被釋放出來的很多4KB 的頁。即使內存空間不夠,需要讓現有的、正在運行的其他程序,通過內存交換釋放出一些內存的頁出來,一次性寫入磁碟的也只有少數的一個頁或者幾個頁,不會花太多時間,讓整個機器被內存交換的過程給卡住。

更進一步地,分頁的方式使得我們在載入程序的時候,不再需要一次性都把程序載入到物理內存中。我們完全可以在進行虛擬內存和物理內存的頁之間的映射之後,並不真的把頁載入到物理內存里,而是只在程序運行中,需要用到對應虛擬內存頁裡面的指令和數據時,再載入到物理內存裡面去。

實際上,我們的操作系統,的確是這么做的。當要讀取特定的頁,卻發現數據並沒有載入到物理內存里的時候,就會觸發一個來自於 CPU 的 缺頁錯誤 (Page Fault)。我們的操作系統會捕捉到這個錯誤,然後將對應的頁,從存放在硬碟上的虛擬內存里讀取出來,載入到物理內存里。這種方式,使得我們可以運行那些遠大於我們實際物理內存的程序。同時,這樣一來,任何程序都不需要一次性載入完所有指令和數據,只需要載入當前需要用到就行了。

通過虛擬內存、內存交換和內存分頁這三個技術的組合,我們最終得到了一個讓程序不需要考慮實際的物理內存地址、大小和當前分配空間的解決方案。這些技術和方法,對於我們程序的編寫、編譯和鏈接過程都是透明的。這也是我們在計算機的軟硬體開發中常用的一種方法,就是 加入一個間接層 。

通過引入虛擬內存、頁映射和內存交換,我們的程序本身,就不再需要考慮對應的真實的內存地址、程序載入、內存管理等問題了。任何一個程序,都只需要把內存當成是一塊完整而連續的空間來直接使用。

總結延伸

現在回到開頭我問你的問題,我們的電腦只要 640K 內存就夠了嗎?很顯然,現在來看,比爾·蓋茨的這個判斷是不合理的,那為什麼他會這么認為呢?因為他也是一個很優秀的程序員啊!

在虛擬內存、內存交換和內存分頁這三者結合之下,你會發現,其實要運行一個程序,「必需」的內存是很少的。CPU 只需要執行當前的指令,極限情況下,內存也只需要載入一頁就好了。再大的程序,也可以分成一頁。每次,只在需要用到對應的數據和指令的時候,從硬碟上交換到內存裡面來就好了。以我們現在 4K 內存一頁的大小,640K 內存也能放下足足 160 頁呢,也無怪乎在比爾·蓋茨會說出「640K ought to be enough for anyone」這樣的話。

不過呢,硬碟的訪問速度比內存慢很多,所以我們現在的計算機,沒有個幾 G 的內存都不好意思和人打招呼。

那麼,除了程序分頁裝載這種方式之外,我們還有其他優化內存使用的方式么?下一講,我們就一起來看看「動態裝載」,學習一下讓兩個不同的應用程序,共用一個共享程序庫的辦法。

閱讀全文

與linux性能瓶頸相關的資料

熱點內容
哪個軟體可以編程手機軟體 瀏覽:554
如東如何學數控編程培訓 瀏覽:5
微信h5頁面怎麼修改 瀏覽:931
手機怎麼無法打開視頻文件夾 瀏覽:840
抖音如何上直播網站 瀏覽:887
錄屏截圖大師保存的文件在哪裡 瀏覽:751
紅河谷第二個版本 瀏覽:895
c語言如何讓整型數據的商為小數 瀏覽:863
怎樣下東西不要密碼 瀏覽:320
小米手機拍照後文件名要怎麼設置 瀏覽:429
每年程序員就業形勢 瀏覽:425
安卓手機如何卸載程序 瀏覽:955
相機能用qq不能用 瀏覽:319
win10如何設置成xp配置文件 瀏覽:748
蘋果隔空傳遞以後文件在哪裡 瀏覽:927
打開ps顯示文件名無效 瀏覽:379
做推廣哪個網站靠譜 瀏覽:588
qq飛車如何綁定好友 瀏覽:873
php編程語言在哪裡 瀏覽:302
矢量文件有哪些格式 瀏覽:790

友情鏈接