免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: pmerofc
打印 上一主题 下一主题

[低水平帖]啥叫堆?啥叫栈? [复制链接]

论坛徽章:
2
程序设计版块每日发帖之星
日期:2015-06-17 22:20:00每日论坛发贴之星
日期:2015-06-17 22:20:00
161 [报告]
发表于 2011-09-16 17:11 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
1
2015年迎新春徽章
日期:2015-03-04 09:49:45
162 [报告]
发表于 2011-09-16 17:30 |只看该作者

  1. witch@natty:~$ sudo cat /proc/1/maps |tail -n 4
  2. 7f447e053000-7f447e10d000 rw-p 00000000 00:00 0                          [heap]
  3. 7fff8e709000-7fff8e72a000 rw-p 00000000 00:00 0                          [stack]
  4. 7fff8e7ff000-7fff8e800000 r-xp 00000000 00:00 0                          [vdso]
  5. ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
复制代码
第一行叫堆,第二行叫栈{:3_189:}

论坛徽章:
3
15-16赛季CBA联赛之山东
日期:2016-10-30 08:47:3015-16赛季CBA联赛之佛山
日期:2016-12-17 00:06:31CU十四周年纪念徽章
日期:2017-12-03 01:04:02
163 [报告]
发表于 2011-09-16 19:00 |只看该作者
回复 162# koolcoy

好的,你亮了。

论坛徽章:
0
164 [报告]
发表于 2011-09-19 11:18 |只看该作者
回复 161# pmerofc

{:3_186:}   好犀利的言辞。  我躲。。 再见。 哦不,永别。

论坛徽章:
0
165 [报告]
发表于 2011-09-19 12:49 |只看该作者
本帖最后由 zavakid 于 2011-09-19 12:50 编辑

回复 114# pmerofc
按照我的理解: MALLOC 系统调用不就是吗?















___________________________
黄金档
入门书

论坛徽章:
1
2015年迎新春徽章
日期:2015-03-04 09:49:45
166 [报告]
发表于 2011-09-19 13:55 |只看该作者
回复 163# captivated

这个是对堆和栈比较合理的一个解释
堆和栈是操作系统层面的东西而不是c语言层面的东西

论坛徽章:
0
167 [报告]
发表于 2011-09-19 14:09 |只看该作者
楼主是个理性的人,逻辑也好,也很自信。 我喜欢。

论坛徽章:
0
168 [报告]
发表于 2011-09-19 18:01 |只看该作者
本帖最后由 狗蛋 于 2011-09-19 18:51 编辑

低水平回复:

通常——尤其是本帖——所说的“堆/栈”,其实是“堆/栈式内存分配”、“操作系统的堆/栈实现”、“操作系统实现的堆/栈管理器”、“语言的堆/栈实现及其管理器”等等等等一大筐概念的大杂烩。关于这种大杂烩的讨论过于高深莫测,非俺这等低水平人士所能置喙。

所以,低水平回复嘛,第一步得容俺先zhuangbility一下,把这一堆大杂烩“正交分解”,然后一个一个慢慢说清楚。


首先,啥叫“堆式内存分配”和“栈式内存分配”?各有什么优缺点?

堆式内存分配是内存管理的一种方式。这个管理方法对内存的申请、释放没有特殊要求,只要你记得申请了就要释放就好。
这种管理方法通用性好(甚至可以模拟栈^_^),但实现复杂,而且有一堆一堆的诸如内存碎片问题、内存池算法适用性和效率等等问题需要处理。

栈式内存分配则严格限制了内存的申请和分配的次序。它要求先申请的内存不能在后申请的内存归还之前归还。这就导致它的用途非常单一,局限于特定的场景(函数调用)和某些特定算法。但也正因为它的单一,使得它的管理算法简单,速度快。加上加速、简化函数/过程调用设计的需要,几乎所有现代CPU都内置了push/pop之类的栈操作指令,大大加速和简化了函数调用/返回功能代码。





显然,堆式管理的内存就是堆,被栈式管理的内存自然就是栈。

那么,堆和栈都在哪里?

无处不在。

不仅无处不在,它们还彼此嵌套、改头换面、难解难分。



比如,一个进程诞生了,操作系统要做些什么?

1、使用自己的堆管理器,为它申请一块空间当作进程控制块
2、在进程控制块里,为它配备一个堆管理器,帮它管理它的3G(或更大)内存空间
3、在进程堆里,替它申请2M字节(可由ulimit改变大小)空间当作运行栈;然后把这个空间一端的地址放到CPU的栈基址寄存器里,这样就可以利用CPU的push/pop系列指令自动替他管理这个栈(相当于硬件实现的栈空间管理器)

——大多情况下,人们所提到的堆和栈,其实就是这个操作系统为进程设置的堆/栈。

然后,这个进程创建了一个线程,又发生了什么?

1、让它仍然使用进程的堆管理器
2、为它另外申请xM字节作为栈空间
3、在系统空间(这点视操作系统而定)为它申请一个线程控制块,把进程堆管理器的地址记录于其中,把栈地址记录于其中

前面有高人质问:没有栈,你怎么实现线程?
嗯,低水平回答:很明显,没有堆,线程才会无法创建;有栈没栈关线程实现鸟事。
至于栈嘛……它是为了方便函数/过程调用的。

那么,没有栈,函数/过程调用操作是否就没法进行了?

答案是:
1、慢一点点而已。注意堆是可以模拟栈的,只要把原来的push+call和pop+ret操作对替换为new/malloc+call和delete/free+ret对即可。
2、抛弃了栈的过程调用,反而可能得到腾飞的机会。
比如近年火热的函数式编程,实际就是想方设法使得函数调用无副作用;这样一来,每个函数都可以“丢”到另外一个线程里去乱序执行——这是一个特别适合并行计算的设计。



回归正题,玩个BT的:
void fun(void)
{
    char buf[4*1024*1024];    //栈上申请4M内存
    tp=thread(thread_fun(buf));        //thread_fun里面实现了一个堆管理器,用以管理buf的使用
    wait_thread(tp);
}

这个buf是堆,还是栈?在哪里是堆,在哪里是栈?



可见,特定时刻特定内存属于堆还是栈,只和该内存当前的被管理方式相关;从一个堆上得到的内存完全可以在接下来当作栈来管理;从一个栈上得来的内存,同样也没人禁止你拿它当堆来提供给他人使用。

作为堆/栈的用户,你不需要关心内存来自何处、由什么方案管理——你只要知道如何申请、如何归还就好了,最多再多知道点性能数据;作为堆/栈的实现者,如何得到内存并不会妨碍你的管理机制;你的用户从你这里取得内存做了什么,你同样无权干涉。



所以,想讨论哪块内存是从堆上得来还是栈上得来,首先必须明确这里提到的堆/栈究竟是哪一级、由谁实现的。

比如,某个平台的某种C编译器上,malloc是CRT的堆内存管理器提供的接口,它要向操作系统的堆内存管理器申请内存,然后以堆的模式分配给用户使用;函数局部变量则是从进程栈里分配的内存,这个内存又是从操作系统管理的堆里面分配的。
而java虚拟机中,虚拟机自身用了宿主系统的堆和栈,但它上面跑的进程所用的堆和栈却完全和宿主系统无关;某些语言甚至可能完全没有堆/栈的概念——虽然最终它还是要使用操作系统的堆/栈。
而apache这类实现中,会先从CRT得到内存,然后把这些内存用它自己的堆管理算法管理(可以搜索下apache的内存池实现);那么这时候利用apache的接口申请内存,用的就是apache的堆。
c++则另外实现了个new/delete接口的堆管理算法(虽然其内部实现可能只是简单的调用系统堆分配算法);而STL则把这个堆管理算法扩充了池管理功能——这个内存池曾经被我替换掉,因为我只需要用stl::hash_map管理我自己的海量同构简单小对象,它的这个内存池过于复杂、缓慢了(当然,这个替换仅仅存在于使用stl::hash_map管理我的小对象时,其它时候用的还是stl的池或者c++的new/delete;当然,可怕的是,当时俺们组还有个牛人,相信微软的VirtualAlloc分配的内存既不在堆上,也不在栈上,是速度最快的,所以大量使用了这个高级东东-.-)——有人能理清我这个系统的堆/栈结构吗?



很显然,不同的平台上的不同编译器下,堆/栈层次树可能是非常不同的。

这些通通都不区分,却热衷于帮C委员会定义哪个东西来自于堆、哪个东西来自于栈——不好意思,这种高水平的讨论,实在不是我等低水平人士所能理解。

论坛徽章:
0
169 [报告]
发表于 2011-09-19 18:12 |只看该作者
堆即是堆,栈即是栈,堆栈堆栈,堆非栈,栈非堆。

论坛徽章:
2
程序设计版块每日发帖之星
日期:2015-06-17 22:20:00每日论坛发贴之星
日期:2015-06-17 22:20:00
170 [报告]
发表于 2011-09-19 19:40 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP