内存分配是系统调用吗?例如,malloc
和new
。堆是否由不同的进程共享并由操作系统管理?私有堆又如何呢?如果堆中的内存分配由操作系统管理,那么这会有多大的开销?
我还想获取一些关于此主题的更多阅读链接。
内存分配是系统调用吗?例如,malloc
和new
。堆是否由不同的进程共享并由操作系统管理?私有堆又如何呢?如果堆中的内存分配由操作系统管理,那么这会有多大的开销?
我还想获取一些关于此主题的更多阅读链接。
malloc
和 new
每次调用并不会执行系统调用。但是,它们使用一种更底层的机制来分配大块内存。在 Windows 上,这个底层机制是 VirtualAlloc()
。我认为在 POSIX 系统上,这与 mmap()
有些类似。这两者都会执行一个系统调用,在操作系统级别上为进程分配内存。随后的分配将使用这些大页面的较小部分,而不会产生系统调用。(假设操作系统带有内存保护。嵌入式设备可能不具备这个功能。)
内存分配是系统调用吗?
不一定是每次分配都需要进行系统调用。只有当进程的堆空间不足以满足请求的内存时,才需要调用内核进行申请。但是C库通常会请求更大的内存块,以降低系统调用的次数。
堆内存由操作系统管理,是否被多个进程共享?私有堆内存呢?
堆内存不会在多个进程之间共享,但是在多个线程之间共享。
内核内存分配的开销完全取决于操作系统。因为这是一个非常常见的事情,在正常情况下您可以期望它是高效的。在内存较低的情况下,情况会变得复杂。
查看 Win32 的分层内存管理。
内存分配总是一个系统调用,但分配是按页面进行的。如果已经有可用空间在已提交页面中,则内存管理器将分配所请求的空间而不更改内核模式。HeapAlloc 最好的一点是,它提供对分配具有精细控制的能力,而 VirtualAlloc 则会将分配舍入为单个页面,这可能导致过度使用内存。
基本上,默认堆和私有堆被视为相同,除了默认堆大小在链接时指定。默认堆大小为 1 MB,并根据需要增长。
malloc()
都会导致一个系统调用(转换到内核模式),但这是完全不正确的。 - Jonathon Reinhart内存分配函数和语言语句,例如malloc/free和new/delete,并不是系统调用。Malloc/free是C/C++库的一部分,而new/delete是C++运行时系统的一部分。它们的调用有时可能会导致系统调用。在其他语言中,内存分配也以类似的方式实现。
一般来说,内存管理无法完全脱离操作系统进行实现,因为内存是主要的系统资源之一,全局内存管理由操作系统内核完成。但由于系统调用比较昂贵,人们尝试设计语言和内存分配库,以最小化系统调用数量。
据我所知,堆是一个进程内实体。这意味着所有的内存分配/释放请求都完全由进程自身管理。操作系统只知道堆的位置和大小,并处理来自进程内存管理系统的两种类型的请求:
add memory page at virtual address X
release memory page from virtual address X
brk(2)
和sbrk(2)
与mmap(2)
一起用于内存分配。我还想提一下,Knuth的《计算机程序设计艺术》第一卷也是关于内存分配方面的很好的参考资料。 - jmbrsyscall
或sysenter
指令的东西。这些指令位于ntdll.dll
中,而不是kernel32.dll
。它们在以Nt
和Zw
开头的函数中,而不是Rtl
。实际上,HeapAlloc
调用RtlAllocateHeap
,后者不一定执行任何系统调用。 - user541686