堆和栈内存是如何管理、实现和分配的?
在 C/C++ 中,我们可以在堆栈或堆上存储变量、函数、成员函数、类的实例.
In C/C++ we can store variables, functions, member functions, instances of a class either on a stack or a heap.
每个是如何实现的?它是如何管理的(高级别的)?gcc 是否预先分配了一块内存用于堆栈和堆,然后根据请求分发出去?原始内存来自RAM吗?
How is each implemented? How is it managed (high level)? Does gcc preallocates a chunk of memory to be used for the stack and heap, and then doles out on request? Is original memory coming from RAM?
可以在堆上而不是在堆栈上分配函数吗?
Can a function be allocated on the heap instead of a stack?
我真正想问的是堆和栈内存的实现和管理.阅读参考问题后, 我没有找到任何可以解决这个问题的内容... 谢谢你的链接
I am really asking about implementation and management of heap and stack memories. After reading referenced question, I didn't find anything that addresses that... thanks for the link
推荐答案
现代操作系统不允许您直接访问硬件 RAM,而是将其抽象为所谓的虚拟内存,它按需映射到 RAM.每个进程通常都有自己的完整地址空间的私有副本.这允许操作系统在运行时在 RAM 中移动进程的内存,甚至将其换出到磁盘.这透明地发生,即进程不会被通知这种重定位并且不需要代码来处理这个.(一些实时应用程序可能会使用技术来防止其内存被换出).
Modern operating systems do not give you direct access to hardware RAM and instead abstract it in so called virtual memory, which it maps to RAM on demand. Each process is usually given its own private copy of the complete address space. This allows the OS to move a process' memory around in RAM at runtime or even swap it out to disk. This happens transparently, i.e. a process is not notified of such a relocation and needs not have code to handle this. (Some real time applications might use techniques to prevent having its memory swapped out).
将目标文件链接到可执行文件或动态库时,链接器会为函数/方法的 cpu 指令和所有全局变量静态分配内存.当操作系统加载可执行或动态库时,它会将这个预先分配的内存映射到实际内存中.
When linking object files to an executable or a dynamic library, the linker statically allocates memory for the cpu instructions of a function/method and for all global variables. When the os loads the executable or dynamic library, it maps this pre-allocated memory into real memory.
在启动时,每个线程都会收到一个称为堆栈的私有内存区域.每次调用函数/方法时,编译器都会插入代码以从堆栈中自动分配(通过增加堆栈指针)足够的内存来保存函数/方法使用的所有参数、局部变量和返回值(如果有).如果编译器确定在处理器寄存器中保留一些变量就足够了,它就不会在堆栈上为其分配内存.当函数/方法返回时,它运行编译器生成的代码以释放(通过递减堆栈指针)此内存.请注意,堆栈中任何对象的析构函数都会在它们定义的块退出时被调用,这可能需要很长时间才能返回.此外,编译器可以自由地重用它认为合适的分配的内存.
On startup, each thread receives a private memory area called the stack. Each time you call a function/method, the compiler inserts code to automatically allocate (by incrementing the stack pointer) enough memory from the stack to hold all parameters, local variables and the return value (if any) the function/method uses. If the compiler determines that it is sufficient to leave some variables in processor registers, it does not allocate memory on the stack for it. When the function/method returns, it runs code generated by the compiler to free (by decrementing the stack pointer) this memory. Note that the destructors of any objects on the stack will be called when the block they are defined in exits, which might be a long time before returning. Also, the compiler is free to reuse the alloacated memory as it sees fit.
当抛出异常时,编译器编译器会插入特殊代码,该代码知道堆栈的布局并且可以展开堆栈直到找到合适的异常处理程序.
When an exception is thrown, the compiler compiler inserts special code that knows the layout of the stack and that can unwind it until finding a suitable exception handler.
与此相反,堆上的内存是使用 new
/delete
分配的,编译器为此插入代码以使用系统库请求或释放内存.
As opposed to this, memory on the heap is allocated using new
/ delete
, for which the compiler inserts code to request or release memory using a system library.
请注意,这是一个简化的描述,让您了解内存分配的工作原理.
Please note that this is a simplified description to give you an idea of how memory allocation works.
相关文章