比如區域性變數是儲存在棧空間中的,今天突然在想棧的上限是多大呢,什麼時候才會棧溢位?
ulimit 命令
linux下使用ulimit 命令可以檢視系統的很多上限值。
可以看到系統設定棧的上限是8m
測試
現在我們寫個程式測試一下
兩種方法:
1、第一種方法:最簡單的是在函式或直接在main()函式裡定義多個區域性變數。
區域性變數一定要初始化,不然可能不會給分配記憶體
2、第二種方法:使用遞迴申請棧空間更合適,測試方便。
#include
#include
int i = 1; //記錄申請的次數
共申請了7m ,第8次申請失敗,因為棧裡面還儲存著其他資料,如main函式的引數,所以第8次申請不足1m,說明執行結果和ulimit檢視的資訊吻合。
3、物理記憶體有4g,那棧空間可以申請4g麼?
設定棧的上限為4g
竟然真的申請了4g,這時候就想到了虛擬記憶體機制和linux交換空間。顯然,這4g真的要物理記憶體給提供那是不夠的,因為除了我們申請的4g ,還有其他程序,核心也需要記憶體空間,所以肯定使用了交換空間,物理記憶體不夠的時候,把暫時不用的記憶體資料臨時儲存到了交換空間。我的交換空間分配了2g 。
申請成功了,但是明顯感覺到了系統卡頓,有時侯在申請了接近3g 的時候會卡一下,此時應該是因為物理記憶體壓力太大,正在往交換空間置換資料吧,然後剩下1g 申請完成。
4、衝動了!這次我們設定棧的上限為 7g > 4g物理記憶體+2g swap
成功了。特別卡,第一次直接系統宕機了。
但是有點不解了,物理記憶體+交換空間 = 6g , 為何能申請7g ? 但是有時候又會中途失敗,不能分配7g。
5、定址空間
需不需要擔心申請記憶體過多,比如像上面遞迴定義了超多字串,那位址夠用麼,變數太多,首位址會不會重複呢?
這個不必擔心,64位系統cpu的定址空間是 2^64 , 0 ~ 0xffffffffffffffff 系統根本用不完這麼大的位址空間。況且我們個人電腦的物理記憶體才是僅僅4g。
所以,64位系統會有很大一部分位址範圍用不到,據說這個叫amd64空洞。
6、申請堆空間
#include
#include
int i = 1; //記錄申請的次數
void func()
; //一次申請 1 m 便於計算
char *p = null;
p = (char*)malloc(1048576);
printf("no.%d %ld 位元組 %p -->
7、32位環境測試上面的**以gcc -m32 編譯執行
這裡也有個問題:
減到足夠小時又開始增大:
有時侯會出現,棧後面用到的位址空間是前面動態申請過的(並未釋放)
8、有時候ulimit -s 設定數值過大時會失敗,還會導致之後設定任何數值都不會成功。登出重新設定就可以了
總之,還是不要隨便更改系統設定的棧大小,不然就會出現上面遇到的幾個問題。一般系統預設設定棧段為8m、4m、2m或1m。
執行緒棧空間的大小
一直做windows伺服器向linux平台的移植工作,對於執行緒的棧空間也是似懂非懂,因而出現了一些問題和總結了部分經驗,供大家分享。在我的伺服器上啟動了286個執行緒後,其後的執行緒啟動失敗了,返回的錯誤原因是12,經查詢定義如下 define enomem 12 out of memory 看來...
執行緒棧空間的大小
一直做windows伺服器向linux平台的移植工作,對於執行緒的棧空間也是似懂非懂,因而出現了一些問題和總結了部分經驗,供大家分享。在我的伺服器上啟動了286個執行緒後,其後的執行緒啟動失敗了,返回的錯誤原因是12,經查詢定義如下 define enomem 12 out of memory 看來...
棧空間大小限制
不同系統的棧空間大小不同,可通過如下方法檢視系統棧大小限制 cat proc 1 limits 該檔案列出了系統資源限制情況 ubuntu 16.04 limit soft limit hard limit units max cpu time unlimited unlimited seconds...