0

我现在想知道这些指令是如何分配内存的。

例如,如果我得到代码怎么办:

x = new int[5]; 
y = new int[5];

如果这些是分配的,它在 RAM 中的实际外观如何?是否为每个变量或块保留了整个块(内存页面或如何称呼它 - 32 位大小为 4KB)为 2 个变量共享?

我在任何手册中都找不到我的问题的答案。感谢所有回复。

我在维基百科上发现:页面的内部碎片很少有进程需要使用确切数量的页面。结果,最后一页可能只是部分填满,浪费了一些内存。较大的页面大小明显增加了这种方式浪费内存的可能性,因为更多可能未使用的内存部分被加载到主内存中。较小的页面大小确保更接近分配中所需的实际内存量。例如,假设页面大小为 1024KB。如果一个进程分配 1025KB,则必须使用两个页面,从而导致 1023KB 的未使用空间(其中一个页面完全消耗 1024KB,而另一个仅消耗 1KB)。

这就是我的问题的答案。总之谢谢各位。

4

3 回答 3

4

您在手册中没有找到它,因为它没有在标准中指定。也就是说,大多数时候 x 和 y 会并排(继续和cout<< hex <<他们的地址)。

但是标准中没有任何内容强制执行此操作,因此您不能依赖它。

于 2010-12-12T08:53:01.220 回答
4

一个典型的分配器实现会首先调用操作系统来获取巨大的内存块,然后为了满足你的请求,它会给你一块内存,这就是所谓的suballocation。如果内存不足,它将从操作系统中获得更多。

分配器必须跟踪它从操作系统获得的所有大块以及它分发给其客户端的所有小块。它还必须接受来自客户端的块。

一个典型的子分配算法会保存一个称为freelist的每个大小的返回块列表,并且总是尝试满足来自 freelist 的请求,只有在 freelist 为空时才进入主块。这种特殊的实现技术对于普通程序来说非常快速且非常有效,尽管如果请求大小到处都是(这对于大多数程序来说并不常见),它具有可悲的碎片属性。

像 GNU 的 malloc 实现这样的现代分配器很复杂,但是已经建立了数十年的经验,应该被认为非常好,以至于很少需要编写自己的专用子分配器。

于 2010-12-12T09:20:26.963 回答
1

每个进程都有不同的段相关联,这些段在进程地址空间中划分:1)文本段 :: 放置代码的位置 2)堆栈段 :: 进程堆栈 3)数据段 :: 这是“新”内存所在的位置预订的。除此之外,它还存储已初始化和未初始化的静态数据(bss 等)。

所以,每当你调用一个新函数(我猜它在内部使用 malloc,但新类使处理内存更安全)时,它会在数据段中分配指定数量的字节。当然,您在运行程序时打印的地址是虚拟的,需要转换为物理地址..但这不是我们的头疼问题,OS 内存管理单元为我们做这件事。

于 2010-12-12T09:00:02.560 回答