天天看點

不同平台下對預設棧大小修改

一、前言:

        在應用程式我們經常需要定義大的數組,數組定義成局部變量非靜态變量,那麼數組就會在棧上配置設定,當數組超過預設棧的大小時,會引起非常記憶體通路。

         一般,在Unix-like平台,棧的大小不是由程式自己來控制的而是由環境變量來控制的,是以就不能通過設定編譯器(像gcc)的任何編譯标志來設定棧的大小;在windows平台下,棧的大小的資訊是包含在可執行檔案中的。它可以在Visual C++的編譯過程中設定。也可以用Microsoft提供的一個叫作:”editbin.exe“程式來直接修改可執行檔案的棧的大小。

二、在一般情況下,不同平台預設棧大小如下

SunOS/Solaris                                8172K bytes          (Shared Version)

Linux                                               10240K bytes 

Windows                                         1024K bytes          (Release Version)

AIX                                                  65536K bytes

三、如果定義數組很大的情況下,那就需要修改預設的棧大小,下面給出幾個平台的修改方法:

1.SunOS/Solaris系統:

        limit                 # 顯示目前使用者的棧大小

        unlimit             # 将目前使用者的棧大小改為不限制大小

        setenv        STACKSIZE 32768 #設定目前使用者的棧大小為 32M bytes

2.Linux系統:

     ulimit -a    #顯示目前使用者的棧大小

     ulimit -s 32768 #将目前使用者的棧大小設定為32M bytes

3. Windows (在編譯過程中的設定):

3.1、windows系統下使用editbin.exe修改棧記憶體

(1)在檔案夾中按下Shift點選右鍵,在右鍵菜單中點選在此處打開PowerShell視窗/在此處打開指令行視窗

(2)在打開的指令視窗中輸入editbin,回車可以看到使用方法。期中/STACK可以修改程式棧大小。(如果沒有該程式,請自行搜尋下載下傳)

不同平台下對預設棧大小修改

(3)通過指令editbin /STACK 10進制棧位元組數 被編輯檔案的路徑/檔案名.exe

修改棧大小,如圖表明修改成功。

不同平台下對預設棧大小修改

注意事項

  • 該工具隻能以指令行方式運作,适用于C/C++等編譯的本機代碼。
  • 該工具同時可以修改32位EXE是否支援超過2GB的記憶體。

3.2、windows系統下使用GCC修改棧記憶體

我們知道,遞歸以及開局部變量都是要占用棧空間的

而Windows預設給每個線程僅僅配置設定1M記憶體(大神說是這樣的)

這時就需要手動調整系統棧大小了。

以下轉自Lynstery:

在用gcc/g++編譯時指定參數

-Wl,–stack=size

size是棧的大小,機關為位元組。

比如我現在要編譯一個名為hh的c++程式,棧的大小要16M,就這樣

不同平台下對預設棧大小修改

如果是像本蒟蒻一樣用dev-c++的,那麼可以

不同平台下對預設棧大小修改

點編譯選項,然後

不同平台下對預設棧大小修改

就可以了

4. AIX系統:

       以root使用者修改/etc/security/limits檔案。在這個檔案中添加相應的使用者的一些限制,下面以tlq使用者的棧大小要修改為64M為例進行說明:

      Su –  root

      Vi /etc/security/limits

檔案的末尾添加如下:

tlq:

     fsize = -1

     core = 2097151

     cpu = -1

     data = -1

     rss = -1

     stack = 65537

     nofiles = -1

修改完之後,再退出系統,重新登陸。此時就可以用ulimit –a來檢視static 大小,此時已經改為了65537K了。

四、 其他在應用程式中設定棧大小的方法

1.通過c++程式代碼控制

        // 設定預設堆棧的大小,機關是位元組,byte,設定為1G

           #pragma comment(linker, "/STACK:1073741824")

2.通過配置程式進行設定,注意機關也是位元組,byte

3.g++設定預設棧大小

(1)将如下代碼寫到主程式前:

 int size = 512 << 20; // 512MB  

    char *p = (char*)malloc(size) + size;  

    __asm__("movl %0, %%esp\n" :: "r"(p));

4. 線程建立時指定線程棧的大小

int ithread_start(void *(run)(void *), void *arg) {
 
pthread_t threadId;
 
pthread_attr_t threadAttr;
 
memset(&threadAttr,0,sizeof(pthread_attr_t));
 
pthread_attr_init(&threadAttr);
 
    int status = 0;
 
    size_t size = 0;
 
    //printf("default size:%d\n", size);
 
    status = pthread_attr_getstacksize(&threadAttr, &size);
 
    if(0 != status)
 
{
 
  printf("pthread_attr_getstacksize err [%d]\n",status);
 
}
 
printf("current thread stack size:%d\n", size);
 
size = 1024*1024;
 
status = pthread_attr_setstacksize(&threadAttr, size);
 
if(0 != status)
 
{
 
printf("pthread_attr_getstacksize err [%d]\n",status);
 
return -1;
 
}
 
printf("set thread stack size:%d\n", size);
 
pthread_attr_setdetachstate(&threadAttr,PTHREAD_CREATE_DETACHED);
 
pthread_create(&threadId, &threadAttr, run, arg);
 
pthread_attr_destroy(&threadAttr);
 
printf("%d\n", (int)threadId);
 
return threadId;
 
}
           

此處代碼修改線程的棧大小為1M

(1) 擷取Linux預設線程棧大小

              ulimite -s

(2)  修改Linux預設線程棧大小

              ulimite -s value