Linux之進(jìn)程的虛擬地址空間,邏輯地址和物理地址,進(jìn)程管理命令
進(jìn)程的虛擬地址空間
進(jìn)程有自己的獨(dú)立地址空間,每啟動(dòng)一個(gè)進(jìn)程,系統(tǒng)就會(huì)為它分配地址空間,虛擬地址空間的大小由計(jì)算機(jī)的硬件平臺(tái)決定,比如32位
的平臺(tái)決定了虛擬地址空間為4G
(因?yàn)?2位系統(tǒng)上指針能夠?qū)ぶ返姆秶?32)
這4G空間的分配如下:
- 由上圖可知,進(jìn)程的虛擬內(nèi)存被分為若干個(gè)“段”;
- 每個(gè)段其實(shí)還被分成了若干個(gè)“塊”,我們將這個(gè)“塊”稱為“頁(yè)”;
- 內(nèi)存的映射(虛擬地址和物理地址之間的轉(zhuǎn)換)也是以“頁(yè)”為單位的;
- 一般來(lái)說(shuō)一頁(yè)的大小4K;
- 交換空間(內(nèi)存‘【這里說(shuō)的是物理內(nèi)存】不夠時(shí)使用,把當(dāng)前不使用的數(shù)據(jù)或者臨時(shí)數(shù)據(jù)放入到交換分區(qū)中),在防止數(shù)據(jù)塊到交換分區(qū)時(shí),也是以"頁(yè)"為單位的,這個(gè)過(guò)程我們稱為“換出”,再由交換分區(qū)調(diào)入內(nèi)存,我們稱為“換入”,整個(gè)過(guò)程即為“換頁(yè)”
注意:虛擬地址一般由段號(hào)、頁(yè)號(hào)、頁(yè)中偏移量構(gòu)成,從而最終計(jì)算出你的物理地址;
缺頁(yè):消除了進(jìn)程全部載入內(nèi)存中,按需調(diào)頁(yè)(也就是換頁(yè));
以上就是Linux的段頁(yè)式內(nèi)存管理
1.內(nèi)核空間(1G)
駐留在內(nèi)存內(nèi),是操作系統(tǒng)的一部分,內(nèi)核空間為內(nèi)核保留,不允許應(yīng)用程序讀寫該區(qū)域或調(diào)用內(nèi)核代碼。
2 棧(stack)
包括以下內(nèi)容和用途:
- 1 函數(shù)的返回值和參數(shù)。
- 2 臨時(shí)變量,包括非靜態(tài)局部變量,以及編譯器自動(dòng)生成的臨時(shí)變量。
- 3 保存上下文:包括函數(shù)調(diào)用前后需保持不變的寄存器。
3 內(nèi)存映射段(mmap)
該區(qū)域用于映射可執(zhí)行文件用到的動(dòng)態(tài)鏈接庫(kù)。若可執(zhí)行文件依賴共享庫(kù),則系統(tǒng)會(huì)為這些動(dòng)態(tài)庫(kù)在從0x40000000開(kāi)始的地址分配相應(yīng)空間,并在程序裝載時(shí)將其載入到該空間。
在Linux 內(nèi)核中,共享庫(kù)的起始地址被往上移動(dòng)至更靠近棧區(qū)的位置。
4 堆(heap)
堆用于存放進(jìn)程運(yùn)行時(shí)動(dòng)態(tài)分配的內(nèi)存段,可動(dòng)態(tài)擴(kuò)張或縮減。堆中內(nèi)容是匿名的,不能按名字直接訪問(wèn),只能通過(guò)指針間接訪問(wèn)。
當(dāng)進(jìn)程調(diào)用malloc©/new(C++)等函數(shù)分配內(nèi)存時(shí),新分配的內(nèi)存動(dòng)態(tài)添加到堆上(擴(kuò)張);當(dāng)調(diào)用free©/delete(C++)等函數(shù)釋放內(nèi)存時(shí),被釋放的內(nèi)存從堆中剔除(縮減) 。
5 .BSS段
.BSS(Block Started by Symbol)段中通常存放程序中以下符號(hào):
- 1 未初始化的全局變量和靜態(tài)局部變量
- 2 初始值為0的全局變量和靜態(tài)局部變量(依賴于編譯器實(shí)現(xiàn))
- 3 未定義且初值不為0的符號(hào)(該初值即common block的大小)
6 數(shù)據(jù)段(.Data)
數(shù)據(jù)段通常用于存放程序中已初始化且初值不為0的全局變量和靜態(tài)局部變量。
數(shù)據(jù)段屬于靜態(tài)內(nèi)存分配(靜態(tài)存儲(chǔ)區(qū)),可讀可寫。
7 代碼段(text)
代碼段也稱正文段或文本段,通常用于存放程序執(zhí)行代碼(即CPU執(zhí)行的機(jī)器指令)。一般C語(yǔ)言執(zhí)行語(yǔ)句都編譯成機(jī)器代碼保存在代碼段。
通常代碼段是可共享的,因此頻繁執(zhí)行的程序只需要在內(nèi)存中擁有一份拷貝即可。
代碼段通常屬于只讀,以防止其他程序意外地修改其指令(對(duì)該段的寫操作將導(dǎo)致段錯(cuò)誤)。
某些架構(gòu)也允許代碼段為可寫,即允許修改程序。
8 保留區(qū)
位于虛擬地址空間的最低部分,未賦予物理地址。
任何對(duì)它的引用都是非法的,用于捕捉使用空指針和小整型值指針引用內(nèi)存的異常情況。
一個(gè)頁(yè)面的大小為4K(212),
——因此進(jìn)程可以使用220個(gè)頁(yè)面
注:絕大多數(shù)處理器上的內(nèi)存頁(yè)的默認(rèn)大小都是 4KB,雖然部分處理器會(huì)使用 8KB、16KB 或者 64KB 作為默認(rèn)的頁(yè)面大小,但是 4KB 的頁(yè)面仍然是操作系統(tǒng)默認(rèn)內(nèi)存頁(yè)配置的主流
邏輯地址
在某一段程序中,我們輸出的變量?jī)?nèi)存地址,其實(shí)是邏輯地址,也就是進(jìn)程的地址空間。
虛擬地址向物理地址的轉(zhuǎn)換依靠的是內(nèi)存管理單元(MMU)
有些時(shí)候,父子進(jìn)程的某個(gè)變量的輸出地址可能相同,只可能是其邏輯地址相同,要想知道它們在內(nèi)存中的物理地址,就必須根據(jù)邏輯地址判斷頁(yè)表號(hào),再根據(jù)各自的頁(yè)表進(jìn)行映射,找到其在內(nèi)存中的具體位置,,不同進(jìn)程的邏輯地址沒(méi)有可比性,但是如果在同一個(gè)進(jìn)程中,若地址相同,那就證明其在同一段物理內(nèi)存中。
如圖,在上述圖片中,假設(shè)父子進(jìn)程的兩個(gè)變量的邏輯地址均為4097,那么其就應(yīng)該在頁(yè)表號(hào)為1的頁(yè)面上且偏移量為2(0-4095)的位置,在根據(jù)頁(yè)表號(hào)映射出其在物理內(nèi)存中的真實(shí)地址。
為什么我們?cè)诔绦蛑胁皇褂梦锢淼刂罚?/strong>
因?yàn)樵谶\(yùn)行程序的目標(biāo)主機(jī)上,我們不知道當(dāng)前哪些物理頁(yè)面是空閑的,如果我們程序?qū)懙亩际俏锢眄?yè)面,比如說(shuō),第一個(gè)進(jìn)程說(shuō)它要用0,1,2,3號(hào)頁(yè)面,假設(shè)其子進(jìn)程也要用0,1,2,3號(hào)頁(yè)面,就沖突了,然后其他頁(yè)面是空閑的。我們?cè)诰幊掏局胁恢榔渌绦驎?huì)用哪些物理頁(yè)面,我們無(wú)法預(yù)知將要運(yùn)行的主機(jī)上哪些物理頁(yè)面是空閑,而且物理頁(yè)面的空閑頁(yè)面是變化的,每次開(kāi)機(jī),空閑的頁(yè)面是不一樣的,我們無(wú)法確定,所以我們只能看邏輯地址,就像跳舞一樣,每個(gè)人有相對(duì)其他人的位置,跳舞的隊(duì)列是不變的,但是有可能在操場(chǎng)跳舞,或者在廣場(chǎng)跳舞。我們只能記錄相對(duì)位置,然后通過(guò)頁(yè)表映射,頁(yè)表的更新,確定哪個(gè)物理頁(yè)面是空閑的。
進(jìn)程管理命令
pstree:樹(shù)狀結(jié)構(gòu)顯示進(jìn)程
ps:報(bào)告程序狀況
這一命令用來(lái)顯示某一時(shí)間點(diǎn)的進(jìn)程信息,這些信息是靜態(tài)的,
若想查看當(dāng)前系統(tǒng)運(yùn)行的動(dòng)態(tài)程序信息 可以使用top
命令。
top:
下面列舉一些常用的選項(xiàng):
ps -ef:顯示所有程序,并以ASCII字符顯示樹(shù)狀結(jié)構(gòu),表達(dá)程序間的相互關(guān)系
- -e和-A的意思是一樣的,即顯示有關(guān)其他用戶進(jìn)程的信息,包括那些沒(méi)有控制終端的進(jìn)程。
- -f顯示用戶id,進(jìn)程id,父進(jìn)程id,最近CPU使用情況,進(jìn)程開(kāi)始時(shí)間等等
ps -l:長(zhǎng)格式輸出
ps -aux:顯示當(dāng)前終端所有進(jìn)程(a)
注意與ps aux區(qū)分:列出正在運(yùn)行的所有進(jìn)程
用戶名 進(jìn)程ID %CPU %內(nèi)存 虛擬內(nèi)存 固定內(nèi)存 終端 狀態(tài) 起始時(shí)間 CPU時(shí)間 程序指令
ps -x:當(dāng)前用戶在所有終端下的進(jìn)程
ps -u:以用戶格式輸出
ps -elf:顯示系統(tǒng)內(nèi)的所有進(jìn)程
列名解釋:
如何殺死一個(gè)進(jìn)程
kill pid
:結(jié)束pid進(jìn)程pkill
:結(jié)束進(jìn)程族kill -9 pid
:強(qiáng)制結(jié)束一個(gè)進(jìn)程該,命令行可以使用`-9`參數(shù)來(lái)強(qiáng)制殺死進(jìn)程
pkill sleep:可以結(jié)束后臺(tái)掛起的所用名叫sleep的進(jìn)程
掛起是一種省電模式,系統(tǒng)將機(jī)器的硬盤,顯示器等外部設(shè)備停止工作,而CPU,內(nèi)存仍然在工作中,等待用戶隨時(shí)喚醒。
kill -stop pid
:掛起一個(gè)進(jìn)程-
jobs
:查看被掛起的程序工作號(hào) command &
:直接在后臺(tái)運(yùn)行程序
用grep命令和kil命令結(jié)合殺死一個(gè)目標(biāo)進(jìn)程
如何在后臺(tái)運(yùn)行一個(gè)進(jìn)程
命令+&
eg:
- sleep 300&
- sleep 300 &
進(jìn)程恢復(fù)
- fg 工作號(hào):將掛起的作業(yè)放回到前臺(tái)執(zhí)行
- bg 工作號(hào):將掛起的作業(yè)放到后臺(tái)執(zhí)行
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
LINUX中詳解AWK內(nèi)建變量FS,NF,NR,RT,RS,ORS,OFS
很多朋友沒(méi)搞告白AWK內(nèi)建變量FS,NF,NR,RT,RS,ORS,OFS的方法和原理,小編給大家總結(jié)了詳細(xì)的內(nèi)容,一起來(lái)學(xué)習(xí)下思路。2017-11-11Linux使用MySQL忘記root密碼及修改MySQL默認(rèn)編碼
本篇文章主要介紹了Linux使用MySQL忘記root密碼及修改MySQL默認(rèn)編碼,碰到這個(gè)問(wèn)題的朋友可以參考下。2016-10-10IO多路復(fù)用之epoll全面總結(jié)(必看篇)
下面小編就為大家?guī)?lái)一篇IO多路復(fù)用之epoll全面總結(jié)(必看篇)。小編覺(jué)得挺不錯(cuò)的?,F(xiàn)在就分享給大家。也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-12-12ubuntu 16.04 LTS 安裝mongodb 3.2.8教程
本篇文章主要介紹了ubuntu 16.04 LTS 安裝mongodb 3.2.8教程,具有一定的參考價(jià)值,有需要的可以了解一下。2017-04-04Ubuntu 16.04源碼編譯安裝Apache 2.4.25教程
這篇文章主要為大家詳細(xì)介紹了Ubuntu 16.04源碼編譯安裝Apache 2.4.25,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-01-01Windows 和 Linux 上Redis的安裝守護(hù)進(jìn)程配置方法
​ Redis是目前最常用的非關(guān)系型數(shù)據(jù)庫(kù)(NOSql)之一,常以Key-Value的形式存儲(chǔ)。這篇文章主要介紹了Windows 和 Linux 上Redis的安裝守護(hù)進(jìn)程配置 ,需要的朋友可以參考下2019-06-06Linux 在Shell腳本中使用函數(shù)實(shí)例詳解
這篇文章主要介紹了Linux 在Shell腳本中使用函數(shù)實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下2017-06-06