[转帖] Linux 下面栈空间大小的实验
比如局部变量是保存在栈空间中的,今天突然在想栈的上限是多大呢,什么时候才会栈溢出?
ulimit 命令
linux下使用ulimit 命令可以查看系统的很多上限值。
- ulimit -a 查看所有
- ulimit -s 查看栈空间的大小
可以看到系统设置栈的上限是8M
测试
现在我们写个程序测试一下
两种方法:
1、第一种方法:最简单的是在函数或直接在main()函数里定义多个局部变量。
局部变量一定要初始化,不然可能不会给分配内存
2、第二种方法:使用递归申请栈空间更合适,测试方便。
#include<stdio.h>
#include<stdlib.h>
int i = 1; //记录申请的次数
void func()
{
char a[1048576]; //一次申请 1 M 便于计算
printf("NO.%d %ld 字节 %p\n",i,sizeof(a),a);
i++;
func();
}
main()
{
func();
}
共申请了7M ,第8次申请失败,因为栈里面还保存着其他数据,如main函数的参数,所以第8次申请不足1M,说明运行结果和ulimit查看的信息吻合。
3、物理内存有4G,那栈空间可以申请4G么?
设置栈的上限为4G
再次运行程序:
竟然真的申请了4G,这时候就想到了虚拟内存机制和linux交换空间。显然,这4G真的要物理内存给提供那是不够的,因为除了我们申请的4G ,还有其他进程,内核也需要内存空间,所以肯定使用了交换空间,物理内存不够的时候,把暂时不用的内存数据临时保存到了交换空间。我的交换空间分配了2G 。
申请成功了,但是明显感觉到了系统卡顿,有时侯在申请了接近3G 的时候会卡一下,此时应该是因为物理内存压力太大,正在往交换空间置换数据吧,然后剩下1G 申请完成。
4、冲动了!这次我们设置栈的上限为 7G > 4G物理内存+2G swap
运行:
成功了。特别卡,第一次直接系统死机了。
但是有点不解了,物理内存+交换空间 = 6G , 为何能申请7G ? 但是有时候又会中途失败,不能分配7G。
5、寻址空间
需不需要担心申请内存过多,比如像上面递归定义了超多字符串,那地址够用么,变量太多,首地址会不会重复呢?
这个不必担心,64位系统CPU的寻址空间是 2^64 , 0 ~ 0xffffffffffffffff 系统根本用不完这么大的地址空间。况且我们个人电脑的物理内存才是仅仅4G。
所以,64位系统会有很大一部分地址范围用不到,据说这个叫AMD64空洞。
6、申请堆空间
#include<stdio.h>
#include<stdlib.h>
int i = 1; //记录申请的次数
void func()
{
char a[1048576] = {'1'}; //一次申请 1 M 便于计算
char *p = NULL;
p = (char*)malloc(1048576);
printf("NO.%d %ld 字节 %p --><-- %p\n",i,sizeof(a),a,p);
i++;
func();
}
main()
{
func();
}
这里有个问题:经多次测试,如果malloc动态申请的内存特别大时,如上图,依次分配的内存地址是递减的,好像不符合堆向上增长的特点。
7、32位环境测试
上面的代码以gcc -m32 编译运行
这里也有个问题:
堆内存地址开始是减小的:
减到足够小时又开始增大:
有时侯会出现,栈后面用到的地址空间是前面动态申请过的(并未释放)
8、有时候ulimit -s 设置数值过大时会失败,还会导致之后设置任何数值都不会成功。注销重新设置就可以了
总之,还是不要随便更改系统设置的栈大小,不然就会出现上面遇到的几个问题。一般系统默认设置栈段为8M、4M、2M或1M。
[转帖] Linux 下面栈空间大小的实验的更多相关文章
- linux查看修改线程默认栈空间大小(ulimit -s)
linux查看修改线程默认栈空间大小 ulimit -s 1.通过命令 ulimit -s 查看linux的默认栈空间大小,默认情况下 为10240 即10M 2.通过命令 ulimit -s 设置大 ...
- 更改Linux默认栈空间的大小
有时候在Linux写C++程序处理大量的数据,程序内部需要分配很大的数组来存放一些数据,但有时候分配的数组太大的话运行时会出现段错误.这种情况可能是分配的数组大小超过了Linux系统的默认栈空间的大小 ...
- 更改Linux栈空间大小
1.通过命令 ulimit -s 查看linux的默认栈空间大小,默认情况下 为10240 即10M 2.通过命令 ulimit -s 设置大小值 临时改变栈空间大小:ulimit -s 102400 ...
- Linux查看磁盘空间大小命令
Linux查看磁盘空间大小命令df -hldf -hl 查看磁盘剩余空间df -h 查看每个根路径的分区大小du -sh [目录名] 返回该目录的大小du -sm [文件夹] 返回该文件夹总M数du ...
- Linux 查看磁盘空间大小
(1)查看文件大小 1. 查看当前文件夹下所有文件大小(包括子文件夹) du -sh 2.查看var目录下文件大小 du -sh var 3.查看指定文件夹下所有文件大小(包括子文件 ...
- Linux查看磁盘空间大小
1. Ubuntu 查看磁盘空间大小命令 df -h Df命令是linux系统以磁盘分区为单位查看文件系统,可以加上参数查看磁盘剩余空间信息, 命令格式: df -hl 显示格式为: 文件系统 容 ...
- [Linux] -Docker修改空间大小
Docker默认空间大小分为两个,一个是池空间大小,另一个是容器空间大小. 池空间大小默认为:100G 容器空间大小默认为是:10G 所以修改空间大小也分为两个: 这里使用centos下的yum进行安 ...
- 查看linux目录剩余空间大小
df命令是linux系统以磁盘分区为单位查看文件系统,可以加上参数查看磁盘剩余空间信息,命令格式: df -hl 显示格式为: 文件系统 容量 已用 可用 已用% 挂载点 Filesystem S ...
- [Linux监控]磁盘空间大小
echo 192.168.10.69>>ip.list ------------------------------------------- #!/bin/bash #注意if和[]之间 ...
随机推荐
- Docker技术入门与实战 第二版-学习笔记-6-仓库
仓库(Repository)是集中存放镜像的地方 一个容易混淆的概念是注册服务器(Registry). 实际上注册服务器是管理仓库的具体服务器,每个服务器上可以有多个仓库,而每个仓库下面有多个镜像. ...
- Node.js实战(三)之第一个Web服务器
这次的示例同样也可以说是HelloWorld,只不过不同的是这是web服务器示例. (1)编写web.js,内容如下: var http = require("http") fun ...
- JAVA 框架 springmvc controller的返回值
一.返回值:ModleView对象. 使用modelAndView.setViewName设置返回的页面.使用modelAndView.addObject设置返回的数据. @RequestMappin ...
- JAVA框架:hibernate(二)
一.事务操作. 代码: @Test public void tr_Up(){ Session session=hibernateUtils.getSession(); Transaction tran ...
- jstl 使用
1.需要导入: 1)jstl.jar 2)standard.jar 引入:jsp相应的核心库:<%@taglib prefix="c" uri="http:// ...
- c语言gets()函数与它的替代者fgets()函数
在c语言中读取字符串有多种方法,比如scanf() 配合%s使用,但是这种方法只能获取一个单词,即遇到空格等空字符就会返回.如果要读取一行字符串,比如: I love BIT 这种情况,scanf() ...
- php实现远程网络文件下载到服务器指定目录(方法一)
PHP实现远程网络文件下载到服务器指定目录(方法一) <?php function getFile($url, $save_dir = '', $filename = '', $type = 0 ...
- 【H5】直接拨打电话
一般<a href="tel:400-663-5999">400-663-5999</a>实现. 而形如<a href="tel:*9204 ...
- 20155317 王新玮《网络对抗技术》实验5 MSF基础应用
20155317 王新玮<网络对抗技术>实验5 MSF基础应用 1. MS08_067安全漏洞 原理:攻击者利用受害者主机默认开放的SMB服务端口445,发送特殊RPC请求,通过MSRPC ...
- mfc 基类与子类
基类(父类) 派生类(子类) 一.基类(父类) 基类(又称为父类,基类与派生类是相对的关系! 通过继承机制,可以利用已有的数据类型来定义新的数据类型.所定义的新的数据类型不仅拥有新定义的成员,而且还同 ...