国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Linux > 正文

探究Linux進程及線程堆棧專題<一>

2024-06-28 13:25:37
字體:
來源:轉載
供稿:網友
探究linux進程及線程堆棧專題<一>

  “你定義了那么多全局變量,系統才給你分配了幾百KB,這樣做是不是太耗內存了?”,一同學問道。

  老早就聽說嵌入式系統各種資源有限啊,不能分配大空間啊要注意節約資源之類的(。。。貌似米神4的配置要完爆我的thinkpad了。。。)。那是不是全局變量的使用真的會占用很大系統內存,而系統真的才分配幾百KB空間給我呢?

  我不信,所以我要嘗試一下:

  全局變量,肯定是要占用內存的,但無論是不是全局變量,只要是已定義的變量都會占用內存,這個和是否是全局的沒啥關系,只是占用的區域不一樣而已(詳見APUE存儲器安排 P153)。

系統怎么可能就給我幾百K的空間,那我的安卓機上的QQ咋動不動就幾十兆的資源占用率?

  不扯淡了,下面就是我的探究內容。


獲得當前進程的堆棧的最大字節長度 :

#define getLimit(name) get_limits(#name,name)//這個#是字符串創建符,可以在宏中創建字符串//只是打印判斷是具體數值還是字符串void PRint_infinite(rlim_t t){    if(RLIM_INFINITY == t)    {        printf("%14s  ","infinite");    }    else    {        printf("%14ld  ",t/1024/1024);    }}//封裝了獲取特定類型數據的最大值static void get_limits(char *name,int resource){    struct rlimit limit;    if(getrlimit(resource,&limit) != 0)    {        printf("get limit error  %s/n",strerror(errno));    }    printf("%-14s  ",name);    print_infinite(limit.rlim_cur);    print_infinite(limit.rlim_max);    putchar('/n');}//入口函數,得到進程的堆棧最大值void GetProcessHeapAndStackLimitSize(){    printf(PARTING_LINE);    printf("%-14s   ","Name");    printf("%13s   ","LimCur(MB)");    printf("%13s   /n","LimMax(MB)");    //RLIMIT_DATA   數據段的最大字節長度: 初始化數據、非初始化及堆的總和    getLimit(RLIMIT_DATA);    //RLIMIT_STACK 棧區的最大字節長度    getLimit(RLIMIT_STACK);    printf("/n");}

用來測試獲取數據是否正確的一個小方法:

遞歸調用,每調用一次消耗系統 棧區 大小1M。自動變量以及每次函數調用時所需保存的信息都放在區。

//用來測試,是否是堆的最大值void GetStackSize(){    static int i = 1;    char xxx[1024*1024] ;///1MB    printf("now i is  :  %d/n",i);        GetStackSize(++i);}

寫個main函數,先調用GET方法,獲得堆棧值再調用測試函數結果如下:

===============================   GetProcessHeapAndStackLimitSize  =================================  Name                LimCur(MB)      LimMax(MB)   RLIMIT_DATA           infinite        infinite  RLIMIT_STACK                 8        infinite  now i is  :  1now i is  :  2now i is  :  3now i is  :  4now i is  :  5now i is  :  6now i is  :  7Segmentation fault (core dumped)

infinite可以理解為不限制,從結果可以看出,當前進程的堆區(其實,這種方法獲得的不是嚴格意義上的堆區,這里獲得的是包括初始化數據、非初始化數據及堆區的總和)的大小是

沒有限制的,而棧區系統卻僅僅分配了8M的空間,也就是說,當前進程下你能使用的局部變量等總和不能超過8M,否則系統就會出現錯誤(Segmentation Fault)。

如果果真如此的話,那我在main函數里直接定義char xxx[8*1024*1024]會是什么情況呢?顯然的,什么都不執行就段錯誤了。

8M顯然是不夠我用的,特別是當我需要各種緩沖區時,那我該如何“擴容”呢?或者我系統確實內存有限不能讓某些應用程序占用過多內存,那么我如何限制它的內存使用呢?

下面就是修改系統 默認配置的方法:

//封裝了設置特定類型數據的最大值static void set_limits(char *name,int resource,rlim_t cur,rlim_t max){    struct rlimit limit;    limit.rlim_cur = cur;    limit.rlim_max = max;    if(setrlimit(resource,&limit) != 0)    {        printf("get limit error  %s/n",strerror(errno));    }    else    {        printf("%s %s  OK /n",__func__,name);    }}void SetProcessHeapAndStackLimitSize(){    printf(PARTING_LINE);    //RLIMIT_DATA   數據段的最大字節長度: 初始化數據、非初始化及堆的總和    rlim_t pref = 10*1024*1024;        setLimit(RLIMIT_DATA,pref,pref*2);    //RLIMIT_STACK 棧區的最大字節長度    setLimit(RLIMIT_STACK,pref*2,pref*4);    }

這樣設置的結果會什么什么樣子呢?我們可以先設置之,然后再重新調用GET方法看看是否設置成功。

//主函數int main(int argc ,char **argv){    GetProcessHeapAndStackLimitSize();    //GetStackSize();//沒有重新設置之前,返回7就崩潰了    SetProcessHeapAndStackLimitSize();    GetProcessHeapAndStackLimitSize();    GetStackSize();//設置后,返回19就崩潰了  ruturn 0;}

結果如下:

===============================   GetProcessHeapAndStackLimitSize  =================================  Name                LimCur(MB)      LimMax(MB)   RLIMIT_DATA           infinite        infinite  RLIMIT_STACK                 8        infinite  ===============================   SetProcessHeapAndStackLimitSize  =================================  set_limits RLIMIT_DATA  OK set_limits RLIMIT_STACK  OK ===============================   GetProcessHeapAndStackLimitSize  =================================  Name                LimCur(MB)      LimMax(MB)   RLIMIT_DATA                 10              20  RLIMIT_STACK                20              40  now i is  :  1now i is  :  2now i is  :  3now i is  :  4now i is  :  5now i is  :  6now i is  :  7now i is  :  8now i is  :  9now i is  :  10now i is  :  11now i is  :  12now i is  :  13now i is  :  14now i is  :  15now i is  :  16now i is  :  17now i is  :  18now i is  :  19Segmentation fault (core dumped)

恰如我們所料,修改參數成功,我們可以使用更多的棧區,也可以限制堆區的使用。

而當我們多次執行時卻發現一個有趣的現象:雖然我們設置成功了,但重新運行程序后,系統還是會僅僅給我們分配8M,可見我們的這個改變僅僅是對當前進程的設置生效,那么如何對系統所有生效呢?見下文分解。

了解這些東西之后,我們有時可能會碰到程序無故掛掉,任何error信息都不打印,甚至GDB都不說問題出在哪里時,大伙可能得考慮一下,是否被系統限制了。

源碼已上傳。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 祁门县| 镇康县| 德江县| 平利县| 轮台县| 屯留县| 天镇县| 香河县| 唐河县| 富蕴县| 苏尼特左旗| 洱源县| 凤凰县| 衡阳县| 横山县| 台东县| 平舆县| 美姑县| 柳江县| 清河县| 香河县| 澄江县| 延安市| 勐海县| 曲沃县| 清水河县| 新晃| 林口县| 隆安县| 六枝特区| 芦溪县| 晋中市| 高平市| 苏尼特右旗| 隆尧县| 重庆市| 沈丘县| 湖州市| 迭部县| 三门县| 墨玉县|