我在谷歌上读到了一些关于堆和堆栈的内容,但大多数答案只是说它的概念描述和差异。
我对其他事情很好奇。
正如标题所说,物理内存上的堆和栈在哪里?
它们的尺寸如何?例如,我的台式电脑使用 12 GB 内存,那么 Heap 是多少?堆栈大小是多少?
谁提出了这两种不同类型的概念?
我可以操纵堆和堆栈的分配吗?如果它们各自占用 50% 的内存(如果堆占用 6 GB 内存,在我的情况下堆栈也占用 6 GB),我可以调整它们的大小吗?
我想知道Linux中每个进程的堆和堆栈的大小。有什么办法可以找到吗?
我发现 sbrk(0) 会给我堆的结尾。但是如何找到堆的起始位置来获取堆大小呢?
另外,关于堆栈大小,是否有任何方法可以通过任何库调用或系统调用找到每个进程的堆栈开头和当前堆栈指针地址?
我想在软实时上下文中使用 Nim,其中内存分配和垃圾收集都表现出过多的延迟。因此,手动内存管理是可取的 - 或者更好的是,专门从堆栈内存工作。
我可以使用 Nim 的哪个子集来实现仅堆栈内存分配?我猜我可以通过缓存的 C 代码中没有 memset 或 memcpy 来判断它是否有效。
我想知道如果我在堆上声明一个类实例(新),即使它们是使用 new 关键字创建的\xe2\x80\x99t,它的成员也会在堆上吗?
\n这是我关于堆栈溢出的第一个问题。如果这是一个“愚蠢”的问题,我很抱歉,但我目前正在学习 C++,并且我对某些事情感到有点困惑。据我了解,在下面的代码中,变量“myVariable”在堆上声明,但在堆栈上的构造函数中实例化。那么它“存在”在哪里——堆上还是栈上?
class MyClass{
int _myVariable;
MyClass(int i){
_myVariable = i;
}
}
Run Code Online (Sandbox Code Playgroud) 这是我的源代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX 500
int main(int argc, char** argv)
{
if (argc != 2)
exit(1);
char str[MAX];
strcpy(str, argv[1]);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我disas使用并得到了以下结果main:gdb
Dump of assembler code for function main:
0x0000000000001145 <+0>: push %rbp
0x0000000000001146 <+1>: mov %rsp,%rbp
0x0000000000001149 <+4>: sub $0x210,%rsp
.
.
.
End of assembler dump.
Run Code Online (Sandbox Code Playgroud)
这里值得注意的是:
0x0000000000001149 <+4>: sub $0x210,%rsp
我的问题是-
为什么会出现$0x210(528 字节),而它应该是$0x1f4(500 字节),正如我所要求的?
在这个Rust 文档中,写道:
字符串是在堆上分配的。
但是,当我查看内存映射时,我发现它是在堆栈中分配的......
让我们考虑下面的基本 Rust 源文件:
// rustc -o string_vs_str -C opt-level=0 -C debuginfo=2 main.rs
fn main() {
let my_string: String = String::from("abc");
let my_str: &str = "def";
println!("{}{}", my_string, my_str);
let my_string_str: &str = my_string.as_str();
println!("my_string_str: {}", my_string_str);
}
Run Code Online (Sandbox Code Playgroud)
让我们根据以下命令在可执行文件上执行 RUST-GDB:
# rust-gdb --batch --command=test.gdb --args ./string_vs_str
set width 0
set height 0
set verbose off
### Set 2 breakpoints
b main.rs:6
b main.rs:8
### Start the process
r
### Display the memory mapping into the …Run Code Online (Sandbox Code Playgroud) 考虑下面的代码,我分配了 4000 个数组,每个数组的长度为 100k:
parentMap := make(map[int][100_000]int)
for i := 0; i < 4000; i++ {
parentMap[i] = [100_000]int{}
time.Sleep(3 * time.Millisecond)
}
Run Code Online (Sandbox Code Playgroud)
如果我在本地运行它并分析其内存使用情况,它开始使用 >2GB 的内存。
现在,如果我们稍微更改一下代码以使用数组切片(但长度也为 100k),如下所示:
parentMap := make(map[int][]int)
for i := 0; i < 4000; i++ {
parentMap[i] = make([]int, 100_000)
time.Sleep(3 * time.Millisecond)
}
Run Code Online (Sandbox Code Playgroud)
在我的机器上,内存峰值约为 73MB。为什么是这样?
我认为这两个片段将使用大致相同的内存,原因如下:
parentMap在这两种情况下,Go 运行时都会在堆上分配 的值。Go 这样做是因为如果它在堆栈上分配这些值,那么parentMap一旦当前函数超出范围, 的值就会全部清除。我读到: https: //go.dev/blog/slices-intro。但找不到解释这一点的实现细节。
在C/C++中,我们可以在堆栈或堆上存储变量,函数,成员函数,类的实例.
每个如何实施?如何管理(高级别)?gcc是否预先分配了一大块内存用于堆栈和堆,然后根据请求发送?原始内存来自RAM吗?
可以在堆而不是堆栈上分配函数吗?
--Clarification--
Run Code Online (Sandbox Code Playgroud)
我真的在询问堆和堆栈存储器的实现和管理.在阅读引用的问题后,我找不到任何解决这个问题的方法......感谢链接
让我们假设我int在函数中定义了一个默认值为0 的本地s 数组:
void test() {
int array[256] = {0};
}
Run Code Online (Sandbox Code Playgroud)
我对此的理解是:
通过将256个零推入堆栈并因此增加堆栈指针,数组将存储在堆栈中.如果数组没有默认值,那么增加堆栈指针就足够了.
现在这是前一个片段生成的汇编代码:
test:
.LFB2:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
pushl %edi
pushl %ebx
subl $1024, %esp
.cfi_offset 7, -12
.cfi_offset 3, -16
leal -1032(%ebp), %ebx
movl $0, %eax
movl $256, %edx
movl %ebx, %edi
movl %edx, %ecx
rep stosl
addl $1024, %esp
popl %ebx
.cfi_restore 3
popl %edi
.cfi_restore 7
popl %ebp
.cfi_restore 5
.cfi_def_cfa 4, 4
ret …Run Code Online (Sandbox Code Playgroud)