linux下栈空间大小(ulimit)

linux下栈空间大小

第一次写博客,很多地方写的不好请多见谅,希望这篇文章对大家有帮助。

    首先说下为什么会写linux下栈空间大小这个内容。在评审同事代码的时候发现代码中有两个函数互相调用,且无法退出导致申请的栈内存无法释放,因此要计算能支持多少次循环。其实这个问题不是太难,只要知道栈空间大小,再除去申请的局部变量大小即可。

    1、如何查看栈空间大小

对于 x86 和 x64 计算机,默认堆栈大小为 1 MB。在 Itanium 芯片组上,默认大小为 4 MB。linux下默认的堆栈空间大小是8M或10M,不同的发行版本可能不太一样。可以使用ulimit指令查看栈空间大小,指令ulimit -s或者ulimit -a如下图:

  使用ulimit -s直接显示出栈空间大小10240,ulimit -a显示所有参数,其中stack size值是10240,表示栈空间大小是10M。注意:这里的单位是KB。我们也可以使用“ulimit -s 数字”来修改栈的大小,如下图将栈空间修改成8M:


ulimit指令参数详解:
-H 设置硬资源限制.
-S 设置 资源限制.
-a 显示当前所有的资源限制.
-c size:设置core文件的最大值.单位:blocks
-d size:设置 数据段的最大值.单位:kbytes
-f size:设置创建文件的最大值.单位:blocks
-l size:设置在内存中锁定进程的最大值.单位:kbytes
-m size:设置可以使用的常驻内存的最大值.单位:kbytes
-n size:设置 内核可以同时打开的 文件描述符的最大值.单位:n
-p size:设置管道 缓冲区的最大值.单位:kbytes
-s size:设置 堆栈的最大值.单位:kbytes
-t size:设置CPU使用时间的最大上限.单位:seconds
-v size:设置 虚拟内存的最大值.单位:kbytes
-u <程序数目>  用户最多可开启的程序数目

2、验证栈空间大小是否是stack size
到这里,大家可能以为问题得到解答了,实际没有,为什么呢?接下去我们通过编写简单的程序来验证一下,验证程序1:
#include <stdio.h>
#include <stdlib.h>
void test(int i)
{
    char temp[1024*1024] = {0};
    
    temp[0] = i;
    temp[0] ++;
    printf("%s %d num = %d!\r\n", __FUNCTION__, __LINE__, temp[0]);
    test(temp[0]);
}
int main(void)
{
    test(0);
    return 0;
}
我们先查找栈空间大小,再编译运行,如下:
经查找栈空间大小是8M,我们每次申请1M的内存空间能申请9次,再加上函数参数、函数返回值、非静态函数等也是放在栈中也需要占用空间。那么,我们能使用的栈空间貌似不是8M,而是9M到10M之间,这是为什么呢?经网上查找资料发现,原来linux中主线程的栈空间要比子线程大,子线程可以使用的栈空间是stack size,而主线程能使用的栈空间要比子线程大很多(2M)。用代码验证一下:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>

pthread_t thread_id;

void test(int i)
{
    char temp[1024*1024] = {0};
    
    temp[0] = i;
    temp[0] ++;
    printf("%s %d num = %d!\r\n", __FUNCTION__, __LINE__, temp[0]);
    test(temp[0]);
}
void *thrd_func(void *arg)
{
    printf("%s %d!\r\n", __FUNCTION__, __LINE__);
    printf("New process:  PID: %d,TID: %u.\r\n",getpid(),pthread_self());
    printf("New process:  PID: %d,TID: %u.\r\n",getpid(),thread_id);
    test(0);
    pthread_exit(NULL); //退出线程
}
int main(void)
{
    if (pthread_create(&thread_id,NULL,thrd_func,NULL)!=0) 
    {
        printf("Create thread error!\r\n");
        exit(1);
    }
    usleep(10000);           //此处一定要加延时,否则子线程还没跑完主线程就结束了。
    return 0;
}
运行并编译,结果:

 可以看到子线程只能申请7M,最大使用的栈空间和stack size一样是8M。




  • 29
    点赞
  • 81
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
根据引用\[1\]中的信息,Linux系统默认的空间限制为8192kb,即每个线程最多只能申请8M的空间。这是为了保护系统免受溢出等问题的影响。空间大小是有限制的,一般是8M,当函数嵌套多次的时候很可能就发生溢出。引用\[3\]中的代码示例就是一个典型的溢出的例子,当函数fun()被递归调用时,每次调用都会在上动态分配一个大小为8192字节的局部变量buf,导致空间不断增长,最终超出了空间的限制。 如果你的系统空间不足8M,可能是因为系统中同时运行的线程数量较多,每个线程都需要一定的空间。当线程数量过多时,系统的总空间就会超过8M的限制。此外,如果你的程序中使用了大量的局部变量或递归调用,也会增加空间的使用量,导致空间不足。 为了解决空间不足的问题,可以考虑以下几种方法: 1. 减少线程数量:如果系统中同时运行的线程数量较多,可以尝试减少线程数量,从而减少总的空间使用量。 2. 减少局部变量的使用:尽量避免在函数中定义过大的局部变量,或者使用动态分配的堆空间来存储大量数据。 3. 避免过深的递归调用:递归调用会导致空间的不断增长,可以考虑使用迭代或其他非递归的方式来替代递归调用。 4. 调整空间大小:可以通过修改系统的配置参数或使用特定的编译选项来调整空间大小,以满足程序的需求。但需要注意,修改空间大小可能会影响系统的稳定性和性能。 总之,空间不足8M可能是由于系统中同时运行的线程数量较多或程序中使用了大量的局部变量或递归调用所导致的。通过减少线程数量、减少局部变量的使用、避免过深的递归调用或调整空间大小等方法,可以解决空间不足的问题。 #### 引用[.reference_title] - *1* [Linux 空间限制 (ulimit -a指令查看限制)(我的ubuntu下每个线程最多只能申请8M空间)(ulimit -s)](https://blog.csdn.net/Dontla/article/details/126208002)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [linux为什么限制用户空间大小](https://blog.csdn.net/faxiang1230/article/details/106242380)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值