堆和栈的区别
堆和栈区别
内存被分为栈内存和堆内存。
栈内存:
当函数被调用时,会产生一个栈内存块供函数使用。这部分通常位于内存空间的顶端,当添加数据时会向下增长。
栈内存会自动的分配或销毁程序或者函数产生的临时数据。堆内存使用LIFO 的方式,最近添加的项目会被最早删除。当程序或者函数停止运行,系统会自动释放他们的栈内存空间,程序会返回上一个执行点。这些让栈的追踪变得简单。
栈内存在管理内存使用上十分有用,因为它的架构可以防止内存泄露。此外,在许多嵌套函数调用的情况下,栈可能会发生泄露和崩溃。
栈中存放:
- 局部变量:函数内部定义的变量存储在栈中。这些变量在函数调用时分配,在函数返回时自动释放。
- 函数调用信息:包括函数的返回地址、参数和局部变量。这些信息存储在栈帧(stack frame)中,每次函数调用都会创建一个新的栈帧。
- 控制流数据:如返回地址和栈指针等,用于控制函数调用和返回。
堆内存:
堆是为动态分配而预留的内存。堆中块的分配和释放没有强制的模式。程序员可以在任意的时间分配或释放内存块。这会导致对内存块的分配和释放的追踪变得更负责。有许多自定义的堆分配器来调整堆的性能,以适应不同使用模式。
堆中存放:
- 动态分配的内存:通过
malloc
、calloc
、realloc
(在C语言中)或new
(在C++中)等函数动态分配的内存块存储在堆中。这些内存块在程序运行时手动分配和释放。 - 全局变量:某些编译器实现中,全局变量和静态变量也存放在堆中。
每一个线程都会有一个栈,但是应用程序通常只有一个堆(尽管为不同类型的分配设置多个堆并不罕见)
常见问题
To what extent are they controlled by the OS or language runtime?
当每一个系统级别的线程被创建时,操作系统会为其分配栈。通常情况下,操作系统由语言运行时调用,为应用程序分配堆。
What is their scope?
栈与线程相联系,所以当线程退出时,栈将被回收。堆通常在程序启动运行时分配,在程序退出时回收
What determines the size of each of them?
栈的大小当线程被创建时就设定了。堆的大小在程序启动时设定,但是当空间需要时可以增长。
参考文章:
- https://www.baeldung.com/java-stack-heap
- https://www.baeldung.com/cs/memory-stack-vs-heap#:~:text=Stack memory is a sort,longer lifespan than stack memory
- https://stackoverflow.com/questions/79923/what-and-where-are-the-stack-and-heap
本文来自博客园,作者:我只有一天的回忆,转载请注明原文链接:https://www.cnblogs.com/cc-coding/articles/18308369