查看機(jī)器上棧大小命令
ulimit -a
或者
ulimit -s
大小不固定,可以用 ulimit -s 進(jìn)行調(diào)整惰拱,默認(rèn)一般為 8M
?棧區(qū)(stack sagment):由操作系統(tǒng)自動(dòng)分配釋放 ,存放函數(shù)的參數(shù)值啊送,局部變量的值等偿短。?如果申請(qǐng)的空間超過(guò)棧的剩余空間時(shí),將提示overflow馋没。因此昔逗,能從棧獲得的空間較小。棧大小是有默認(rèn)值的篷朵,如果申請(qǐng)的臨時(shí)變量太大的話就會(huì)超過(guò)棧大小勾怒,造成棧溢出。
堆棧溢出?就是不顧堆棧中分配的局部數(shù)據(jù)塊大小(在棧中分配的局部數(shù)據(jù)塊大小和局部變量的聲明的大小有關(guān))款票,向該數(shù)據(jù)塊寫入了過(guò)多的數(shù)據(jù)控硼,導(dǎo)致數(shù)據(jù)越界,結(jié)果覆蓋了老的堆棧數(shù)據(jù)(包括函數(shù)的返回地址)艾少。 或者解釋為在長(zhǎng)字符串中嵌入一段代碼卡乾,并將過(guò)程的返回地址覆蓋為這段代碼的地址,這樣當(dāng)過(guò)程返回時(shí)缚够,程序就轉(zhuǎn)而開始執(zhí)行這段自編的代碼了.這東西很像病毒幔妨。
堆(heap):一般由程序員分配釋放, 若程序員不釋放谍椅,程序結(jié)束時(shí)可能由OS回收误堡,分配方式倒是類似于鏈表。堆是用于存放進(jìn)程運(yùn)行中被動(dòng)態(tài)分配的內(nèi)存段雏吭,它的大小并不固定锁施,可動(dòng)態(tài)擴(kuò)張或縮減。當(dāng)進(jìn)程調(diào)用malloc等函數(shù)分配內(nèi)存時(shí)杖们,新分配的內(nèi)存就被動(dòng)態(tài)添加到堆上(堆被擴(kuò)張)悉抵;當(dāng)利用free等函數(shù)釋放內(nèi)存時(shí),被釋放的內(nèi)存從堆中被剔除(堆被縮減)
BSS段:存放的是未初始化的全局變量和靜態(tài)變量摘完。BSS是英文Block Started by Symbol的簡(jiǎn)稱姥饰。BSS段屬于靜態(tài)內(nèi)存分配。
數(shù)據(jù)段:初始化過(guò)的數(shù)據(jù)(Data)孝治,存放已初始化的全局變量列粪、靜態(tài)變量(全局和局部)审磁、常量數(shù)據(jù)。數(shù)據(jù)段屬于靜態(tài)內(nèi)存分配岂座。
代碼段:存放CPU執(zhí)行的機(jī)器指令态蒂,代碼區(qū)是可共享,并且是只讀的掺逼。這部分區(qū)域的大小在程序運(yùn)行前就已經(jīng)確定
用戶空間就是用戶進(jìn)程所在的內(nèi)存區(qū)域吃媒,相對(duì)的,系統(tǒng)空間就是操作系統(tǒng)占據(jù)的內(nèi)存區(qū)域吕喘。用戶進(jìn)程和系統(tǒng)進(jìn)程的所有數(shù)據(jù)都在內(nèi)存中赘那。
為什么要?jiǎng)澐钟脩艨臻g和系統(tǒng)空間呢?當(dāng)然是有必要的氯质。操作系統(tǒng)的數(shù)據(jù)都是存放于系統(tǒng)空間的募舟,用戶進(jìn)程的數(shù)據(jù)是存放于用戶空間的。分開來(lái)存放闻察,就讓系統(tǒng)的數(shù)據(jù)和用戶的數(shù)據(jù)互不干擾拱礁,保證系統(tǒng)的穩(wěn)定性。分開存放辕漂,管理上很方便呢灶,而更重要的是,將用戶的數(shù)據(jù)和系統(tǒng)的數(shù)據(jù)隔離開钉嘹,就可以對(duì)兩部分的數(shù)據(jù)的訪問(wèn)進(jìn)行控制鸯乃。這樣就可以確保用戶程序不能隨便操作系統(tǒng)的數(shù)據(jù),這樣防止用戶程序誤操作或者是惡意破壞系統(tǒng)跋涣。處于用戶態(tài)的程序只能訪問(wèn)用戶空間缨睡,而處于內(nèi)核態(tài)的程序可以訪問(wèn)用戶空間和內(nèi)核空間。
?Linux使用兩級(jí)保護(hù)機(jī)制:0級(jí)供內(nèi)核使用陈辱,3級(jí)供用戶程序使用奖年,每個(gè)進(jìn)程有各自的私有用戶空間(0~3G),這個(gè)空間對(duì)系統(tǒng)中的其他進(jìn)程是不可見的沛贪,最高的1GB字節(jié)虛擬內(nèi)核空間則為所有進(jìn)程以及內(nèi)核所共享陋守。
用戶態(tài)切換到內(nèi)核態(tài)的3種方式
a. 系統(tǒng)調(diào)用
這是用戶態(tài)進(jìn)程主動(dòng)要求切換到內(nèi)核態(tài)的一種方式,用戶態(tài)進(jìn)程通過(guò)系統(tǒng)調(diào)用申請(qǐng)使用操作系統(tǒng)提供的服務(wù)程序完成工作利赋,比如fork()實(shí)際上就是執(zhí)行了一個(gè)創(chuàng)建新進(jìn)程的系統(tǒng)調(diào)用水评。而系統(tǒng)調(diào)用的機(jī)制其核心還是使用了操作系統(tǒng)為用戶特別開放的一個(gè)中斷來(lái)實(shí)現(xiàn),例如Linux的int 80h中斷隐砸。
b. 異常
當(dāng)CPU在執(zhí)行運(yùn)行在用戶態(tài)下的程序時(shí),發(fā)生了某些事先不可知的異常蝙眶,這時(shí)會(huì)觸發(fā)由當(dāng)前運(yùn)行進(jìn)程切換到處理此異常的內(nèi)核相關(guān)程序中季希,也就轉(zhuǎn)到了內(nèi)核態(tài)褪那,比如缺頁(yè)異常。
c. 外圍設(shè)備的中斷
當(dāng)外圍設(shè)備完成用戶請(qǐng)求的操作后式塌,會(huì)向CPU發(fā)出相應(yīng)的中斷信號(hào)博敬,這時(shí)CPU會(huì)暫停執(zhí)行下一條即將要執(zhí)行的指令轉(zhuǎn)而去執(zhí)行與中斷信號(hào)對(duì)應(yīng)的處理程序,如果先前執(zhí)行的指令是用戶態(tài)下的程序峰尝,那么這個(gè)轉(zhuǎn)換的過(guò)程自然也就發(fā)生了由用戶態(tài)到內(nèi)核態(tài)的切換偏窝。比如硬盤讀寫操作完成,系統(tǒng)會(huì)切換到硬盤讀寫的中斷處理程序中執(zhí)行后續(xù)操作等武学。
這3種方式是系統(tǒng)在運(yùn)行時(shí)由用戶態(tài)轉(zhuǎn)到內(nèi)核態(tài)的最主要方式祭往,其中系統(tǒng)調(diào)用可以認(rèn)為是用戶進(jìn)程主動(dòng)發(fā)起的,異常和外圍設(shè)備中斷則是被動(dòng)的火窒。