天天看点

不同平台下对默认栈大小修改

一、前言:

        在应用程序我们经常需要定义大的数组,数组定义成局部变量非静态变量,那么数组就会在栈上分配,当数组超过默认栈的大小时,会引起非常内存访问。

         一般,在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