内存分配是系统调用吗?例如,malloc
和new
。堆是由不同进程共享并由操作系统管理的。私有堆怎么样?如果堆中的内存分配由操作系统管理,这有多贵?
我还希望有一些链接到我可以阅读更多关于这个主题的地方。
答案 0 :(得分:49)
通常,malloc
和new
在每次调用时都不会执行系统调用。但是,它们使用较低级别的机制来分配大页面的内存。在Windows上,较低的机制是VirtualAlloc()
。我相信POSIX系统,这有点等同于mmap()
。这两个都执行系统调用以在OS级别为进程分配内存。后续分配将使用这些大页面的较小部分而不会发生系统调用。
堆通常是内部进程,不在进程之间共享。如果需要,大多数操作系统都有一个用于分配shared memory的API。 Boost.Interprocess库中提供了这些API的便携包装器。
如果您想了解有关内存分配和与操作系统关系的更多信息,您应该查看一本关于操作系统的好书。我总是建议Andrew C. Tanenbaum Modern Operating Systems,因为它很容易阅读。
答案 1 :(得分:24)
(假设一个具有内存保护的操作系统。例如在嵌入式设备中可能不是这种情况。)
内存分配是系统调用吗?
不一定每次分配。如果内核的堆不足以满足所请求的分配,则该进程需要调用内核,但C库通常会在执行此操作时请求更大的块,目的是减少系统调用的数量。
堆是否由不同进程共享并由操作系统管理。那么私有堆呢?
进程之间不共享堆。它虽然在线程之间共享。
内核内存分配系统调用的成本完全取决于操作系统。由于这是一个非常普遍的事情,你可以期望它在正常情况下是有效的。在RAM较低的情况下,事情变得复杂。
答案 2 :(得分:19)
请参阅Win32中的分层内存管理。
内存分配始终是系统调用,但分配是作为页面进行的。如果提交的页面中有可用空间,则内存管理器将分配所请求的空间而不更改内核模式。关于HeapAlloc的最好的事情是,它提供了对Virtual Alloc为单个页面分配的分配的精细控制。这可能会导致内存使用过多。
除了在链接时指定默认堆大小外,默认堆和私有堆基本相同。默认堆大小为1 MB,并根据需要增长。
答案 3 :(得分:3)
内存分配函数和语言语句(如malloc / free和new / delete)不是系统调用。 Malloc \ free是C \ C ++库的一部分,new \ delete是C ++运行时系统的一部分。两者的调用偶尔会导致系统调用。在其他语言中,内存分配以类似的方式实现。
一般情况下,如果不涉及操作系统,就无法实现内存管理,因为内存是主要的系统资源之一,并且由于OS内核进行了全局内存管理。但是由于系统调用相对昂贵,人们试图设计语言和内存分配库,以最大限度地减少系统调用。
据我所知,heap是一个进程内实体。这意味着所有内存分配/解除分配请求都完全由进程本身管理。操作系统只知道堆的位置和大小,并为进程内存管理系统提供两种类型的请求:
add memory page at virtual address X
release memory page from virtual address X
本地内存管理系统在确定堆内存池中没有足够内存以及它确定堆内存池中有太多内存时请求这些服务。 尽管内存分配通常以最小化系统调用量的方式设计,但它仍然比堆栈上的内存分配更加昂贵。这是因为堆的内存分配\解除分配算法比堆栈的内存分配\解除分配算法复杂得多,而且价格昂贵。