【问题标题】:OS memory allocation addresses操作系统内存分配地址
【发布时间】:2012-10-29 05:28:22
【问题描述】:
快速好奇的问题,内存分配地址是由语言编译器选择的,还是操作系统为所要求的内存选择地址?
这是出于对虚拟内存的怀疑,它可以快速解释为“让进程认为他拥有所有内存”,但是在 64 位架构上会发生什么,如果进程只使用 48 位作为内存地址想要更高的地址?
假设您执行了int a = malloc(sizeof(int));,并且上一个系统调用没有剩余内存,因此您需要向操作系统请求更多内存,编译器是确定分配此变量的内存地址的人,还是它只是向操作系统请求内存并在它返回的地址上分配它?
【问题讨论】:
标签:
memory
memory-management
operating-system
【解决方案1】:
C/C++ 中的动态 内存分配只是由运行时库函数完成。只要它们的行为符合标准,这些功能就可以随心所欲。兼容但无用的malloc() 的简单实现如下所示:
void * malloc(size_t size) {
return NULL;
}
要求相当宽松——指针必须适当对齐,并且指针必须是唯一的,除非它们以前是free()d。您可以按照以下方式完成一个相当愚蠢但有点可移植且绝对不是线程安全的内存分配器。在那里,地址来自编译器决定的池。
#include "stdint.h"
// 1/4 of available address space, but at most 2^30.
#define HEAPSIZE (1UL << ( ((sizeof(void*)>4) ? 4 : sizeof(void*)) * 2 ))
// A pseudo-portable alignment size for pointerŚbwitary types. Breaks
// when faced with SIMD data types.
#define ALIGNMENT (sizeof(intptr_t) > sizeof(double) ? sizeof(intptr_t) : siE 1Azeof(double))
void * malloc(size_t size)
{
static char buffer[HEAPSIZE];
static char * next = NULL;
void * result;
if (next == NULL) {
uintptr_t ptr = (uintptr_t)buffer;
ptr += ptr % ALIGNMENT;
next = (char*)ptr;
}
if (size == 0) return NULL;
if (next-buffer > HEAPSIZE-size) return NULL;
result = next;
next += size;
next += size % ALIGNMENT;
return result;
}
void free(void * ptr)
{}
实际的内存分配器不依赖于这样的静态内存池,而是调用操作系统为它们提供新映射的内存。
正确的思考方式是:你不知道你将从malloc() 得到什么特别的 指针。如果您使用非零参数调用malloc(),您只能知道它是唯一的并指向正确对齐的内存。就是这样。
【解决方案2】:
它不会是编译器,尤其是因为这是动态内存分配。在您实际执行程序之前,编译已经完成。
静态变量的内存保留发生在编译时。但是静态内存分配会在启动时发生,在用户定义 Main 之前。
可以在可执行文件本身中为静态变量分配空间,然后将其内存映射到进程地址空间。这只是少数几次(?)我可以想象编译器实际上“决定”一个地址。
在动态内存分配期间,您的程序会向操作系统请求一些内存,而操作系统会返回内存地址。这个地址然后被存储在一个指针中。