为什么 malloc() 被视为库调用而不是系统调用?

发布于 2025-01-12 20:36:26 字数 58 浏览 1 评论 0原文

为什么 malloc() 被视为标准 C 库函数而不是系统调用?操作系统似乎负责处理所有内存分配请求。

Why is malloc() considered a standard C library function and not a system call? It seems like the OS is responsible for handling all memory allocation requests.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

瑕疵 2025-01-19 20:36:26

当然可能mallocfree实现为系统调用,但很少这样做。

系统调用是对操作系统内核的调用。例如,在 POSIX 系统(Linux、UNIX...)上,readwrite 是系统调用。当 C 程序调用 read 时,它可能会调用一个包装器,该包装器会执行向内核发出请求所需的任何操作,然后将结果返回给调用者。

事实证明,进行内存管理最有效的方法是使用较低级别的系统调用(参见brksbrk)来扩展当前进程的数据段,然后使用库调用(mallocfree 等)来管理该段内的内存。该管理不需要与内核进行任何交互;这只是在当前进程中执行的指针操作。如果 malloc 函数需要比当前可用的内存更多的内存,则会调用系统调用,例如 brksbrk,但是许多 malloc 调用根本不需要与内核进行任何交互。

上面的内容是针对 Linux/POSIX/UNIX 系统的。例如,Windows 的细节会有所不同,但总体设计可能相似。

请注意,某些 C 标准库函数通常直接作为系统调用实现。 time 就是一个例子(但正如 Nick ODell 在评论中指出的那样,time 调用通常可以在不与内核交互的情况下执行)。

It would certainly be possible to implement malloc and free as system calls, but it's rarely if ever done that way.

System calls are calls into the OS kernel. For example, on POSIX systems (Linux, UNIX, ...), read and write are system calls. When a C program calls read, it's probably calling a wrapper that does whatever is needed to make a request to the kernel and then return the result to the caller.

It turns out that the most efficient way to do memory management is to use lower-level system calls (see brk and sbrk) to expand the current process's data segment, and then use library calls (malloc, free, etc.) to manage memory within that segment. That management doesn't require any interaction with the kernel; it's all just pointer manipulation performed within the current process. The malloc function will invoke a system call such as brk or sbrk if it needs more memory than is currently available, but many malloc calls won't require any interaction with the kernel at all.

The above is fairly specific to Linux/POSIX/UNIX systems. The details will be a bit different for Windows for example, but the overall design is likely to be similar.

Note that some C standard library functions are typically implemented directly as system calls. time is one example (but as Nick ODell points out in a comment, a time call can often be performed without interacting with the kernel).

唠甜嗑 2025-01-19 20:36:26

看起来操作系统负责处理所有内存分配请求。

好吧,既是又不是。

实际上,它更多地取决于您的特定系统,而不是 C。

大多数操作系统都会在一定大小的主干中分配内存。通常称为页面。页面大小可能不同。在特定系统上可能有多种受支持的页面大小。 4K 是许多系统上的典型页面大小,但可能支持更大的大页面。

但是,是的......最终只有一个实体可以分配内存。操作系统。除非你使用的是裸机,其他代码可以处理它 - 如果甚至支持的话。

为什么 malloc() 被视为标准 C 库函数而不是系统调用?

简短的答案是:因为 malloc 不是操作系统/系统调用。时期。

详细说明一下。一次 malloc 调用可能会导致系统调用,但下一次 malloc 可能不会。

例如:您使用 malloc 请求 100 个字节。 malloc 可能决定调用操作系统。操作系统为您提供 4K。在下一个 malloc 中,您请求 500 字节。然后“中间层”可以只提供来自先前系统调用已经提供的主干的 500 字节。

所以不...通过malloc进行内存分配可能不会导致任何系统调用来分配更多内存。

这完全取决于您的特定系统。而 C 标准并不关心。

malloc 不是系统调用。 malloc 在需要时使用其他系统调用。

It seems like the OS is responsible for handling all memory allocation requests.

Well, both yes and no

It actually depends more on your specific system than it depend on C.

Most OS allocates memory in trunks of some size. Typically called a page. The page size may differ. And on a specific system there may be several supported page-sizes. 4K is a typical page-size on many systems but huge page much bigger may be supported.

But yes... at the end of the day there is only one entity that can allocate memory. The OS. Unless you are on bare-metal where other code can handle it - if even supported.

Why is malloc() considered a standard C library function and not a system call?

The short answer is: Because malloc isn't a OS/systemcall. Period.

To elaborate a bit more. One malloc call may lead to a systemcall but the next malloc may not.

For instance: You request 100 bytes using malloc. malloc may decide to call the OS. The OS gives you 4K. In your next malloc you request 500 byte. Then the "layer in between" can just give the 500 bytes from the trunk already provided by the previous syscall.

So no... memory allocation via malloc may not lead to any syscall for alocation of more memory.

It's all very dependent on your specific system. And the C standard doesn't care.

But malloc is not a syscall. malloc uses other syscalls when needed.

流年里的时光 2025-01-19 20:36:26

看起来操作系统负责处理所有内存分配请求。

出于性能原因,每次程序需要内存时都向操作系统请求内存并不是一个好主意。造成这种情况的原因有几个:

  1. 操作系统以称为页的单位管理内存。页的长度通常为 4096 字节。 (但某些架构或操作系统使用更大的页面。)操作系统无法为进程分配内存在比页面还小的块中。

    假设您需要 10 个字节来存储一个字符串。分配 4096 字节并且只使用前 10 个字节是非常浪费的。内存分配器可以向操作系统请求一个页面,并将该页面分割成更小的分配。

  2. 系统调用需要上下文切换。相对于在同一程序中调用函数,上下文切换的成本很高(在 x86 系统上约为 100 ns)。同样,最好请求更大的内存块,并将其重新用于多次分配。

为什么 malloc() 被视为库调用而不是系统调用?

对于某些库调用,例如read(),库中的实现非常简单:它调用同名的系统调用。对库函数 read() 的一次调用会产生对 read() 的一次系统调用。将 read() 描述为系统调用是合理的,因为所有工作都是在内核中完成的。

malloc() 的情况更为复杂。没有名为 malloc() 的系统调用,库调用 malloc() 实际上会使用系统调用 sbrk()brk()mmap(),具体取决于您的分配大小和您使用的实现。大多数时候,它根本不进行系统调用!

如何实现malloc()有许多不同的选择。因此,您会看到许多不同的竞争实现,例如 jemalloctcmalloc

It seems like the OS is responsible for handling all memory allocation requests.

For performance reasons, it's not a good idea to ask the OS for memory every time the program needs memory. There are a few reasons for this:

  1. The OS manages memory in units called pages. Pages are typically 4096 bytes long. (But some architectures or operating systems use larger pages.) The OS can't allocate memory to a process in a chunk smaller than a page.

    Imagine you need 10 bytes to store a string. It would be very wasteful to allocate 4096 bytes and only use the first 10. A memory allocator can ask the OS for a page, and slice that page into smaller allocations.

  2. A system call requires a context switch. A context switch is expensive, (~100 ns on x86 systems) relative to calling a function in the same program. Again, it is better to ask for a larger chunk of memory, and re-use it for many allocations.

Why is malloc() considered a library call and not a system call?

For some library calls, like read() the implementation in the library is very simple: it calls the system call of the same name. One call to the library function read() produces one system call to read(). It's reasonable to describe read() as a system call, because all the work is being done in the kernel.

The story with malloc() is more complicated. There's no system call called malloc(), and the library call malloc() will actually use the system calls sbrk(), brk(), or mmap(), depending on the size of your allocation and the implementation you're using. Much of the time, it makes no system call at all!

There are many different choices in how to implement malloc(). For that reason, you'll see many different competing implementations, such as jemalloc, or tcmalloc.

冷情 2025-01-19 20:36:26

为什么 malloc() 被视为标准 C 库函数而不是系统调用?

因为它是 C 标准库的一部分。

看起来操作系统负责处理所有内存分配
请求。

它不是。操作系统通常会为给定进程分配一些内存空间,但之后如何使用内存则取决于进程。使用标准库进行内存分配等操作可以将您的代码与任何给定操作系统的详细信息隔离开来,从而使您的代码更加可移植。给定的 malloc 实现最终可能会进行系统调用来获取内存,但是否执行或不执行或有时执行是一个实现细节。

Why is malloc() considered a standard C library function and not a system call?

Because it's part of the C standard library.

It seems like the OS is responsible for handling all memory allocation
requests.

It's not. An operating system typically allocates some memory space for a given process, but how the memory is used after that is up to the process. Using the standard library for things like memory allocation insulates your code from the details of any given operating system, which makes your code a lot more portable. A given implementation of malloc might ultimately make a system call to obtain memory, but whether it does or doesn't or does some of the time is an implementation detail.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文