五月激情久久_黄色国产_狠狠爱网址_av黄色在线观看_日韩a视频_一级少妇女片

欢迎您访问从栈上分配内存更快?解析栈指针移动的本质!

从栈上分配内存更快?解析栈指针移动的本质

更新时间:2024-09-28 16:41:20作者:佚名

栈区内存申请与释放

毫无疑问,从堆栈中分配内存更快,因为从堆栈中分配内存只是堆栈指针的移动。这意味着什么?什么是“堆栈指针移动”?以x86平台为例,栈上的内存分配是如何实现的?很简单,只有一行指令:

sub?$0x40,%rsp

这行代码被称为“堆栈指针移动”,其本质就是这张图:

leave是什么意思?怎么读_leave是什么意思译怎么读_leave怎么意思

这很简单。寄存器esp存放当前栈顶地址。由于堆栈的增长方向是从高地址到低地址,所以当增加堆栈时,需要将堆栈指针向下移动,这就是sub指令的作用。该指令将堆栈指针向下移动 64 个字节(0x40),因此可以说在堆栈上分配了 64 个字节。

可以看到,在栈上分配内存其实非常非常简单,简单到只是一条机器指令。

栈区的内存释放也很简单,只需要一条机器指令:

leave

leave指令的作用是将栈基地址赋给esp,使栈指针指向上一个栈帧的栈顶,然后弹出ebp,使ebp指向栈底前一个堆栈帧的:

leave是什么意思译怎么读_leave怎么意思_leave是什么意思?怎么读

你看,执行leave指令后,ebp和esp都指向了上一个栈帧,相当于弹出栈帧。这样,栈1占用的内存就无效了,没有任何用处。显然这就是我们经常提到的内存回收,所以一条简单的leave指令就可以回收栈区的内存。

leave是什么意思?怎么读_leave怎么意思_leave是什么意思译怎么读

关于栈、栈帧和栈区,更详细的解释可以参考我写的这篇文章。

接下来我们看堆区的内存申请和释放。

堆区内存申请与释放

与在堆栈区域分配内存相反的是堆内存分配。在堆区分配内存有多复杂?太复杂了,我用了两篇文章来讲解“堆内存分配”的实现原理? 》。

在堆区域申请和释放内存是一个相对复杂的过程,因为堆本身需要程序员(内存分配器实现者)来管理,而堆栈则由编译器维护。堆区的维护也涉及到内存。分配和释放,但是这里的内存分配和释放显然不会像栈区那么简单。一句话leave是什么意思?怎么读leave是什么意思?怎么读,这里就是内存的按需分配和释放。本质是堆区中每块分配的内存的生命周期都是No,这是由程序员决定的。我倾向于将动态内存分配和释放视为去停车场寻找停车位。

leave是什么意思译怎么读_leave怎么意思_leave是什么意思?怎么读

这显然会使问题变得复杂。我们必须仔细维护哪些内存已分配,哪些是空闲的,如何找到空闲内存,如何回收程序员不需要的内存块,同时不能造成严重后果。在栈区分配和释放内存时无需担心内存碎片问题。同时,当堆区内存空间不足时贝语网校,需要对堆区进行扩展等,这些使得在堆区申请内存比在栈区分配内存更加复杂。还有很多,具体可以参考我写的这两篇文章“””。

说了这么多,在堆上申请内存比在栈上申请内存慢多少呢?

接下来,我们来写一些代码来实验一下。

显示代码

void?test_on_stack()?{
??int?a?=?10;
}

void?test_on_heap()?{
??int*?a?=?(int*)malloc(sizeof(int));
??*a?=?10;
??free(a);
}

void?test()?{
??auto?begin?=?GetTimeStampInUs();
??for?(int?i?=?0;?i?????test_on_stack();
??}
??cout<<"test?on?stack?"<<((GetTimeStampInUs()?-?begin)?/?1000000.0)<
??begin?=?GetTimeStampInUs();
??for?(int?i?=?0;?i?????test_on_heap();
??}
??cout<<"test?on?heap?"<<((GetTimeStampInUs()?-?begin)?/?1000000.0)<}

这段代码很简单,这里有两个函数:

然后我们在测试函数中分别调用这两个函数,每个函数被调用一亿次,并记录其运行时间。得到的测试结果为:

test?on?stack?0.191008
test?on?heap?20.0215

可以看到,在栈上总共花费的时间只有0.2s左右,而在堆上分配的时间却是20s,相差一百倍。

值得注意的是,编译程序时并没有开启编译优化。开启编译优化后的时间消耗如下:

test?on?stack?0.033521
test?on?heap?0.039294

可以看到它们几乎是一样的,但是这是为什么呢?显然从常识来看,在栈上分配速度更快。问题是什么?

现在我们开启了编译优化,优化后的代码运行速度是不是更快了呢?我们看一下编译优化后生成的指令:

test_on_stackv:
??400f85:???????55??????????????????????push???%rbp
??400f86:???????48?89?e5????????????????mov????%rsp,%rbp
??400f89:???????5d??????????????????????pop????%rbp
??400f8a:???????c3??????????????????????retq

test_on_heapv:
??400f8b:???????55??????????????????????push???%rbp
??400f8c:???????48?89?e5????????????????mov????%rsp,%rbp
??400f8f:???????5d??????????????????????pop????%rbp
??400f90:???????c3??????????????????????retq

啊哈,编译器太聪明了。很明显注意到这两个函数中的代码实际上什么也没做。尽管我们专门将变量a的值赋值为10,但后来我们根本没有使用变量a。 ,所以编译器为我们生成了一个空函数,而上面的机器指令实际上对应了一个空函数。

小风哥在这里反复添加代码,没有骗过编译器。我试图增加分配变量a的复杂性,但编译器仍然巧妙地生成了一个空函数。反正我没尝试过。可以看出,现代编译器足够智能,生成的机器指令非常高效。关于如何编写更好的基准测试,以便我们可以看到打开编译优化时这两种内存分配方法的比较。任何对此有任何疑问的人都欢迎。请各位有经验或者有编译优化经验的同学留言。

最后我们看一下这两种内存分配方式的定位。

栈内存和堆内存的区别

首先,我们必须认识到堆栈是先进后出的结构。堆栈区域会随着函数调用级别的增加而增加,并随着函数调用的完成而减少。因此,栈不需要任何“管理”;同时,由于栈的性质,栈上申请的内存的生命周期与函数是绑定的。当函数调用完成后,其所占用的栈帧内存将失效,并且栈的大小是有限的。你不能在堆栈上申请太多的内存,就像这段C代码:

void?test()?{
??int?b[10000000];
??b[1000000]?=?10;
}

这段代码运行后会核心出来。原因是堆栈区域的大小非常有限。在堆栈上分配大块数据会使堆栈爆裂。这就是所谓的堆栈溢出:

leave是什么意思译怎么读_leave是什么意思?怎么读_leave怎么意思

前额。 。 。抱歉,图片放错地方了,应该是这个Stack Overflow:

leave怎么意思_leave是什么意思?怎么读_leave是什么意思译怎么读

抱歉,我又搞错了,不过你明白的。

堆不同。堆上分配的内存的生命周期由程序员控制。程序员决定何时申请内存、何时释放内存。因此,必须对堆进行管理。堆区域非常广阔。区,当堆区不足时,会请求操作系统扩展堆区以获得更多的地址空间。

当然,虽然堆区给了程序员更大的灵活性,但是程序员需要保证内存在不使用的时候被释放,否则就会出现内存泄漏。在栈上申请内存就不存在这个问题。

总结

栈区是自动管理的,堆区是手动管理的。显然,在堆栈区域上分配内存比在堆区域上分配内存要快。当栈区申请的内存使用场景有限时,程序员在申请内存时就得更加小心。大多数都是依赖堆区,但是如果栈区申请的内存满足要求的话,我个人更倾向于使用栈区内存。

希望这篇文章能够帮助大家了解堆区和栈区。

为您推荐

句子篇章朗读技巧及考查题型解析

本题型在考查单词发音准确性的基础上,还考查考生朗读的完整性和流畅性。连读是指在同一个意群中,前一个单词末尾的音和后一个单词开头的音连起来读的现象。重读单词一般是句子中表达实际意义的词。非重读单词通常是句中无实际意义的词。一个单词是否重读,与它在句子中表达的意思相关。

2024-09-28 16:19

dinosaurs是什么意思_dinosaurs怎么读_dinosaurs翻译_用法_发音_词组_同反义词

dinosaurs的基本释义为 基本解释 n. <生>恐龙( dinosaur的名词复数 );守旧落伍的人,过时落后的东西等等。贝语网校(www.nenqi.cn)为您提供dinosaurs发音,英语单词dinosaurs的音标,dinosaurs中文意思,dinosaurs的过去式,dinosaurs双语例句等相关英语知识。

2024-09-27 12:27

dining是什么意思_dining怎么读_dining翻译_用法_发音_词组_同反义词

dining的基本释义为 基本解释 n. 进餐v. 吃饭,进餐( dine的现在分词 );设宴款待,请客等等。贝语网校(www.nenqi.cn)为您提供dining发音,英语单词dining的音标,dining中文意思,dining的过去式,dining双语例句等相关英语知识。

2024-09-27 12:25

dignified是什么意思_dignified怎么读_dignified翻译_用法_发音_词组_同反义词

dignified的基本释义为 基本解释 adj. 有尊严的;庄严的;高贵的;厚重等等。贝语网校(www.nenqi.cn)为您提供dignified发音,英语单词dignified的音标,dignified中文意思,dignified的过去式,dignified双语例句等相关英语知识。

2024-09-27 12:23

digits是什么意思_digits怎么读_digits翻译_用法_发音_词组_同反义词

digits的基本释义为 基本解释 n. 数字( digit的名词复数 );手指,足趾等等。贝语网校(www.nenqi.cn)为您提供digits发音,英语单词digits的音标,digits中文意思,digits的过去式,digits双语例句等相关英语知识。

2024-09-27 12:23

digital是什么意思_digital怎么读_digital翻译_用法_发音_词组_同反义词

digital的基本释义为 基本解释 adj. 数字的;数据的;手指的;指状的n. 手指;(钢琴等的)琴键;数字等等。贝语网校(www.nenqi.cn)为您提供digital发音,英语单词digital的音标,digital中文意思,digital的过去式,digital双语例句等相关英语知识。

2024-09-27 12:22

加载中...
主站蜘蛛池模板: 夜夜爽亚洲人成8888 | 99色热| 免费亚洲精品 | 第一色网站 | 亚洲精品视频网站在线观看 | 91视频在线免费观看 | 午夜免费看毛片 | 国产精品永久久久久 | 91成人在线视频 | 99精品久久久| 99国产精品久久久久久久床豆 | 日韩精品成人免费视频 | 91亚洲精品久久久 | 国产亚洲99天堂一区 | 国产成人久久久精品免费澳门 | 亚洲免费福利视频 | 九九九九色 | 亚洲天堂成人在线视频 | 久久久久久国产精品久久 | 91视色| 国产福利在线小视频 | 91高清视频在线 | 成年在线免费视频 | 免费看麻豆视频 | 91视频高清免费 | 91| 天天爽夜夜爽人人爽一区二区 | 在线观看日韩视频 | 国产一级片免费看 | 人人干影院| 天干夜天干夜天天免费视频 | 国产区免费 | 亚洲最大福利视频 | 亚洲精品久久久久久首妖 | 亚洲免费福利视频 | 在线观看深夜福利 | 国产一线 | 91文字幕巨乱亚洲香蕉 | 在线观看深夜福利 | 亚洲综合天堂网 | 免费观看男女啪啪乱淫播放 |