操作系统内存分配

OS memory allocation

提问人:Reza Farshad 提问时间:11/16/2023 更新时间:11/17/2023 访问量:61

问:

操作系统如何为进程分配内存? 我的意思是,例如,在 unix 家族中,操作系统是否使用 malloc 函数进行此分配?

memory schaduler 是否使用 malloc func? 在操作系统中执行此分配的例程是什么? 谢谢

操作系统 动态内存分配

评论

0赞 Scott Hunter 11/16/2023
什么是“记忆破坏者”?
0赞 MSalters 11/16/2023
另请参阅 stackoverflow.com/questions/6530355/...

答:

0赞 MSalters 11/16/2023 #1

如果操作系统使用,那将是一个先有鸡还是先有蛋的问题,因为通常必须使用操作系统来获取内存(除非可以重用您之前的内存。mallocmallocmallocfree

此外,还适用于字节粒度。每个现代操作系统都使用由页面组成的“虚拟内存”。典型的页面是 4 kB,而不是一个字节。实际页面大小取决于 CPU 支持。malloc

操作系统中使用的例程特定于操作系统,是操作系统内部的,与应用程序程序员无关。您可能唯一需要知道的是如何询问操作系统 - 但通常您不会直接针对操作系统进行编程。您的语言运行时将为您处理该问题(请参阅)。malloc

评论

0赞 Reza Farshad 11/16/2023
谢谢,但我的问题仍然存在。
0赞 Reza Farshad 11/16/2023
操作系统使用例程分配内存,程序集例程使用机器指令。
0赞 Reza Farshad 11/16/2023
例如,在 X86 指令集中,似乎没有针对此特定任务的指令(当然有🙂)
0赞 MSalters 11/16/2023
@RezaFarshad:在 x86 上,页面在页表中进行管理。这是一个内存结构,所以可以正常工作。无需特殊说明。MOV
0赞 user123 11/17/2023 #2

操作系统如何为进程分配内存?

操作系统使用自己的内存分配器来选择虚拟内存中未使用的页面。每个进程的虚拟内存空间是相同的,但每个进程都有一组不同的页表,这些页表通过更改基指针寄存器中的值进行切换,基指针寄存器是包含页表根的物理地址(第一级页表的第一个字节的地址)的寄存器。

CPU 的每个内核都有自己的一组寄存器,每个内核一次执行一个进程的指令。操作系统使用计时器进行进程调度,为每个进程提供一个时间片,并允许它们在特定内核上执行。计时器是引发异步中断的硬件机制,因此操作系统可以只将进程调度到核心,并等待计时器触发中断以通知其时间片已结束。然后,在将基指针寄存器的值更改为新的页表集后,操作系统可以自由地在该内核上计划另一个进程。

这样,操作系统可以选择虚拟内存中的任何页面,只要构成页面的虚拟内存中的地址范围转换为物理内存或 RAM 的不同范围。它是读取页表以将虚拟地址转换为物理地址的 CPU,因此它是一种硬件机制。操作系统所需的管理是更改存储在物理内存中的页表中的值(因此只需使用 MOV 指令),以确保翻译落在不同的页帧(地址的物理内存范围)上。

该过程通过将参数放在标准寄存器(Linux 上的标准是 System V)中以及用于内存分配的系统调用号放在另一个标准寄存器中来进行系统调用。然后,该进程执行 CPU 指令,该指令跳转到 CPU 提供的特殊系统调用寄存器中操作系统指定的地址,或者根据可用的 CPU 机制(其架构,例如 ARM、x86、RISC-V 等)触发中断。然后,操作系统的系统调用处理程序(它的第一条指令位于存储在该特殊寄存器中的地址)根据系统调用的数量和提供的参数确定要做什么。对于内存分配,它将找出虚拟内存中一些可用的页面,更改页表以允许进程访问它,并在将该页面的第一个地址放入返回寄存器或堆栈中后返回调用进程。函数中的指令可以假定该寄存器中的值包含地址或错误代码,并访问所请求分配大小中的所有地址,例如,如果进程要求 1 页,则函数后面的指令可以访问其中的所有内容。returned_address + page_size amount of bytes

我的意思是,例如,在 unix 家族中,操作系统是否使用 malloc 函数进行此分配?

函数 malloc 是一个 c 标准函数,由操作系统的标准库实现。标准库使用系统调用来请求内存。无论使用哪种语言,OS 都会根据计算机的当前使用情况提供有用或必需的系统调用。如果系统调用有用或需要,则无论高级语言是否需要它,操作系统都必须提供它。对于内存分配,操作系统必须提供服务,高级语言与此无关。高级语言是一种抽象,它将使用系统调用来根据其标准要求完成工作。对于 malloc,它要求可以为进程提供一系列地址,在这些地址中它可以读取和写入,因此标准库使用特定操作系统上可用的功能来提供它。

操作系统使用例程分配内存,程序集例程使用机器指令。

这没有任何意义。计算机是电气设备,它们与电力一起工作。它是用 2 种状态表示数字的电子电路,这些状态用 1 和 0 抽象表示。1 或 0 的实际电气表示由硬件决定,并根据一系列标准进行选择,例如功耗、组件尺寸,例如,我可以将这个特定的电压与纳米级的晶体管一起使用吗?等。

计算机以电子方式移动数据并对这些数据进行计算,这是它们唯一做的事情。当您在计算机上看到外部效果时,例如在键盘上打字并看到屏幕上的某些变化,这是代表您按下的键的数据,电子电路更改数据(屏幕上呈现的图像用数据表示),最终您的屏幕显示该新图像后,显卡与您的屏幕进行电子交互以使其显示该新图像。

高级语言是文本语言,包括汇编语言。编程语言是一种文本标准。这些语言由它们支持的代码行定义。语言的编译器是该语言的实现。编码器编写文本(即代码行),并调用读取文本(您的代码)的编译器。然后,它将编写一个可执行文件,其中包含将实现标准(C,C++,Java,Python等语言)中指定的结果的指令,用于其目标的特定体系结构(例如x86,ARM等)。它还必须适应操作系统平台,以处理与系统调用相关的所有内容,但这通常被标准库抽象出来。可执行文件中的指令调用库中的函数,此函数执行更低级的工作,即正确进行系统调用以实现正确的结果。

评论

0赞 Reza Farshad 11/17/2023
Wow wonderful answer.you mean in each entry of process table there is a address of begining of a process.and program counter points to this entry so jump to this address.before all this loader must load the program code to memory and probably it uses MOV instruction to do this.Move data ( data is program codes) from hard disk buffer to registers and memory.
0赞 user123 11/18/2023
A process really is just a data structure held in kernel areas of the virtual memory with different page tables since PTI (see stackoverflow.com/questions/77427689/…). That data structure specifies the memory allocated to the process in ranges of virtual addresses e.g. from SOME_ADDRESS to SOME_OTHER_ADRESS is allocated to your process. The data structure most lilely points to other data structures for threads (Thread Control Blocks or TCB).
0赞 user123 11/18/2023
Each thread belongs to a process and shares its address space. It depends on implementation (between OSes) but the process could not specify the value for registers and let TCBs handle it. When a thread is running on a core, the values for its registers in its TCB are not valid. When it gets switched out, its current registers are saved in its TCB for its next scheduled run.
0赞 user123 11/18/2023
The Program Counter cannot be modified explicitely with a mov so you have to jump to an address using or something similar. It is essentially like you mentionned : the executable file which contains the compiled program's code mentions a first instruction and the OS will jump to it after loading the code in main memory or RAM from the hard-disk. For loading memory from an hard-disk, see another of my answer on cs.stackexchange.com : cs.stackexchange.com/questions/142525/…jmp