使用top -p 进程号,查看结果如下
跳出语句块后,ch栈空间应该被释放,而top的结果并无减少,
甚至连buffers和caches的值也没有相应增加。
为什么?
实验发现,类似std::string和std::map也会有同样的结果,即top显示的进程内存总是停留在峰值。
如果是top不准确的话,试问采用什么方式查看进程内存才是正确的?
8 个解决方案
#1
ps + cat /proc/pid/status
#2
搜“内存延迟释放”
#3
前后输出完全一样,请试验过再行评论
#4
“跳出语句块后,ch栈空间应该被释放”
这种说法完全就是错误的
1. 首先栈的内存是程序一开始就申请好,程序结束时才会释放的。 Linux 之类的系统好像有个栈自动扩展,启动的时候栈很小,只有 4K,如果使用的栈超出了边界,内核会自动扩展,但是并没有栈自动收缩的说法。
2. 对于栈内存所谓的申请和释放其实只是对 esp 寄存器的加减而已,并不涉及到向系统申请和归还内存的操作。而且对 esp 寄存器的操作也只是在函数的开头和结尾进行,绝不会在每一个语句块的开始和结束进行一次。语句块中的变量只不过是 C++ 语法限制你不能再语句块外直接访问而已。
3. 对于申请了而没有实际使用的内存,操作系统通常只会保留地址空间给你,并不会分配实际的物理内存。物理内存可能会延迟到你写入的时候才会为你写入的地方分配(通常是以 4k 的粒度来分配的)。
4. 对于没有使用的变量,编译器完全可以给你优化掉,当它不存在的。
这种说法完全就是错误的
1. 首先栈的内存是程序一开始就申请好,程序结束时才会释放的。 Linux 之类的系统好像有个栈自动扩展,启动的时候栈很小,只有 4K,如果使用的栈超出了边界,内核会自动扩展,但是并没有栈自动收缩的说法。
2. 对于栈内存所谓的申请和释放其实只是对 esp 寄存器的加减而已,并不涉及到向系统申请和归还内存的操作。而且对 esp 寄存器的操作也只是在函数的开头和结尾进行,绝不会在每一个语句块的开始和结束进行一次。语句块中的变量只不过是 C++ 语法限制你不能再语句块外直接访问而已。
3. 对于申请了而没有实际使用的内存,操作系统通常只会保留地址空间给你,并不会分配实际的物理内存。物理内存可能会延迟到你写入的时候才会为你写入的地方分配(通常是以 4k 的粒度来分配的)。
4. 对于没有使用的变量,编译器完全可以给你优化掉,当它不存在的。
#5
你这点内存 。。
#6
ps + cat /proc/pid/status
前后输出完全一样,请试验过再行评论
你这点内存 。。
10M小吗?不小了。楼上说的挺靠谱,不过不知道为什么Windows下的任务管理器为什么能够实时且精确地表示进程内存大小。。。
#7
在占用内存空间较大的局部数组声明的前面加static将其从堆栈数据段挪到全局数据段即可避开因局部数组大小超过默认堆栈大小1MB造成程序不能正常运行的问题。
static cha[10*1024*1024]={0};
static cha[10*1024*1024]={0};
#8
“跳出语句块后,ch栈空间应该被释放”
这种说法完全就是错误的
1. 首先栈的内存是程序一开始就申请好,程序结束时才会释放的。 Linux 之类的系统好像有个栈自动扩展,启动的时候栈很小,只有 4K,如果使用的栈超出了边界,内核会自动扩展,但是并没有栈自动收缩的说法。
2. 对于栈内存所谓的申请和释放其实只是对 esp 寄存器的加减而已,并不涉及到向系统申请和归还内存的操作。而且对 esp 寄存器的操作也只是在函数的开头和结尾进行,绝不会在每一个语句块的开始和结束进行一次。语句块中的变量只不过是 C++ 语法限制你不能再语句块外直接访问而已。
3. 对于申请了而没有实际使用的内存,操作系统通常只会保留地址空间给你,并不会分配实际的物理内存。物理内存可能会延迟到你写入的时候才会为你写入的地方分配(通常是以 4k 的粒度来分配的)。
4. 对于没有使用的变量,编译器完全可以给你优化掉,当它不存在的。
我的另一个帖子针对第三条有质疑,麻烦移步赐教,拜谢。
#1
ps + cat /proc/pid/status
#2
搜“内存延迟释放”
#3
ps + cat /proc/pid/status
前后输出完全一样,请试验过再行评论
#4
“跳出语句块后,ch栈空间应该被释放”
这种说法完全就是错误的
1. 首先栈的内存是程序一开始就申请好,程序结束时才会释放的。 Linux 之类的系统好像有个栈自动扩展,启动的时候栈很小,只有 4K,如果使用的栈超出了边界,内核会自动扩展,但是并没有栈自动收缩的说法。
2. 对于栈内存所谓的申请和释放其实只是对 esp 寄存器的加减而已,并不涉及到向系统申请和归还内存的操作。而且对 esp 寄存器的操作也只是在函数的开头和结尾进行,绝不会在每一个语句块的开始和结束进行一次。语句块中的变量只不过是 C++ 语法限制你不能再语句块外直接访问而已。
3. 对于申请了而没有实际使用的内存,操作系统通常只会保留地址空间给你,并不会分配实际的物理内存。物理内存可能会延迟到你写入的时候才会为你写入的地方分配(通常是以 4k 的粒度来分配的)。
4. 对于没有使用的变量,编译器完全可以给你优化掉,当它不存在的。
这种说法完全就是错误的
1. 首先栈的内存是程序一开始就申请好,程序结束时才会释放的。 Linux 之类的系统好像有个栈自动扩展,启动的时候栈很小,只有 4K,如果使用的栈超出了边界,内核会自动扩展,但是并没有栈自动收缩的说法。
2. 对于栈内存所谓的申请和释放其实只是对 esp 寄存器的加减而已,并不涉及到向系统申请和归还内存的操作。而且对 esp 寄存器的操作也只是在函数的开头和结尾进行,绝不会在每一个语句块的开始和结束进行一次。语句块中的变量只不过是 C++ 语法限制你不能再语句块外直接访问而已。
3. 对于申请了而没有实际使用的内存,操作系统通常只会保留地址空间给你,并不会分配实际的物理内存。物理内存可能会延迟到你写入的时候才会为你写入的地方分配(通常是以 4k 的粒度来分配的)。
4. 对于没有使用的变量,编译器完全可以给你优化掉,当它不存在的。
#5
ps + cat /proc/pid/status
前后输出完全一样,请试验过再行评论
你这点内存 。。
#6
ps + cat /proc/pid/status
前后输出完全一样,请试验过再行评论
你这点内存 。。
10M小吗?不小了。楼上说的挺靠谱,不过不知道为什么Windows下的任务管理器为什么能够实时且精确地表示进程内存大小。。。
#7
在占用内存空间较大的局部数组声明的前面加static将其从堆栈数据段挪到全局数据段即可避开因局部数组大小超过默认堆栈大小1MB造成程序不能正常运行的问题。
static cha[10*1024*1024]={0};
static cha[10*1024*1024]={0};
#8
“跳出语句块后,ch栈空间应该被释放”
这种说法完全就是错误的
1. 首先栈的内存是程序一开始就申请好,程序结束时才会释放的。 Linux 之类的系统好像有个栈自动扩展,启动的时候栈很小,只有 4K,如果使用的栈超出了边界,内核会自动扩展,但是并没有栈自动收缩的说法。
2. 对于栈内存所谓的申请和释放其实只是对 esp 寄存器的加减而已,并不涉及到向系统申请和归还内存的操作。而且对 esp 寄存器的操作也只是在函数的开头和结尾进行,绝不会在每一个语句块的开始和结束进行一次。语句块中的变量只不过是 C++ 语法限制你不能再语句块外直接访问而已。
3. 对于申请了而没有实际使用的内存,操作系统通常只会保留地址空间给你,并不会分配实际的物理内存。物理内存可能会延迟到你写入的时候才会为你写入的地方分配(通常是以 4k 的粒度来分配的)。
4. 对于没有使用的变量,编译器完全可以给你优化掉,当它不存在的。
我的另一个帖子针对第三条有质疑,麻烦移步赐教,拜谢。