在应用程序我们经常需要定义大的数组,数组定义成局部变量非静态变量,那么数组就会在栈上分配,当数组超过默认栈的大小时,会引起非常内存访问。
一般,在Unix-like平台,栈的大小不是由程序自己来控制的而是由环境变量来控制的,所以就不能通过设置编译器(像gcc)的任何编译标志来设置栈的大小;在windows平台下,栈的大小的信息是包含在可执行文件中的。它可以在Visual C++的编译过程中设置,但是在gcc中是不可行的。也可以用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 (在编译过程中的设置):
1). 选择 "Project->Setting".
2). 选择 "Link".
3). 选择 "Category"中的 "Output".
4. 在 "Stack allocations"中的"Reserve:"中输栈的大小,例如: 32768
如下图所示:
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了。
5. C++中设置默认堆栈的大小
(1)通过程序代码控制
// 设置默认堆栈的大小,单位是字节,byte,设置为1G
#pragma comment(linker, "/STACK:1073741824")
(2)通过配置程序进行设置,注意单位也是字节,byte
6.g++设置默认栈大小
(1)将如下代码写到主程序前:
int size = 512 << 20; // 512MB
char *p = (char*)malloc(size) + size;
__asm__("movl %0, %%esp\n" :: "r"(p));
7. 线程创建时指定线程栈的大小
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