当前位置: 首页 > 科技观察

Linux内存的分配和释放是什么?

时间:2023-03-12 19:20:11 科技观察

理解内存分配机制(共享映射和请求分页)通过pmap命令可以获取用户进程逻辑地址空间映射的内存信息:pmap-x$pid其中-x表示获取详细信息.下面是一个例子:pmap-x$(pidofemacs)|head-20其中,“Address(地址)”是指进程的逻辑地址空间。“Kbytes”栏代表逻辑地址对应的容量,“RSS”栏代表实际物理内存容量,单位为Kb。由于分页机制的存在,这个值一般小于“Kbytes”的值。“Mapping”一栏是逻辑内存的映射方式,其中“[annon]”表示通过malloc函数分配的堆空间(匿名内存),“[stack]”是进程的栈空间。这两个映射是将物理内存映射到进程的逻辑内存。“emacs-25.3”、“libpixbufloader-svg.so”等文件名表示它们进行文件映射,与磁盘上的文件一一对应。当这些文件被读入缓存时,相应的内存空间被映射到进程的逻辑内存中。当多个程序使用相同的文件映射(共享库)时,它们可以共享磁盘缓存中的相同空间,从而节省物理内存的使用。这种技术就是“共享映射”技术。除了共享库,进程的fork还使用了共享映射技术。当父进程fork子进程时,Linux内核实际上并不复制内存中的内容,而是将映射到子进程的逻辑地址空间与映射到父进程逻辑地址空间的部分内容共享。里面。但是,为了防止父进程和子进程的内存操作相互干扰,Linux内核在进行共享映射时,会将相应的内存区域临时设置为写保护。当一个进程试图操作内存时,会抛出一个只读异常。内核检测到这个异常后,会复制操作的内存页,这样两个进程就可以独立写了。这种写时复制机制称为“写时复制”。它不会读取文件的所有内容,而是先标记“文件内容已映射到逻辑地址空间”。当进程访问逻辑地址空间时,由于没有对应的物理内存,会导致换页错误异常。内容检测到异常后,会以内存页为单位将需要的部分读入内存。这种只读取需要的内容的机制称为请求分页。了解内存释放机制当其他进程需要新的物理内存时,涉及到如何释放或换出尚有数据剩余的物理内存。当需要新的物理内存时,记录在Inactive(file)和Active(file)中的内存页会先被释放,只需要将脏数据写入文件再释放内存页。Inactive(anon)和Active(anon)内存页在释放前需要交换到物理磁盘上的swap。具体来说,Linux会在进程页表上做一个标记,标记出换出的内存对应的逻辑地址。当进程访问逻辑地址时,会产生相应物理内存不存在的异常。Linux内核检测到这个异常后,会重新从swap中加载数据到空闲内存中,并重新配置页表信息。Linux内核使用两种机制来加速换出:一种是预读。当某个内存页需要换入时,Linux内核会将后续的几个内存页一起换入。因为进程很有可能会连续访问多个内存页。预读页数由内核参数vm.page-cluster决定为2^vm.page-cluster。另一个是交换缓存。即一个内存页被换入后,原来的数据仍然保留在物理磁盘上的交换空间中,这种状态的内存会被记录在“交换缓存”列表中。这样,当“交换缓存”中记录的内存页的数据需要再次换出时,就不需要再次换入了。查看/proc/进程ID/statuscat/proc/$(pidofemacs)/statusName:emacsUmask:0022State:S(sleeping)Tgid:6769Ngid:0Pid:6769PPid:1TracerPid:0Uid:1000100010001000Gid可以查看各个进程的内存使用情况:1000100010001000FDSize:64Groups:9869981000NStgid:6769NSpid:6769NSpgid:6769NSsid:6769VmPeak:567040kBVmSize:567040kBVmLck:0kBVmPin:0kBVmHWM:241176kBVmRSS:241176kBRssAnon:204544kBRssFile:36604kBRssShmem:28kBVmData:231712kBVmStk:1596kBVmExe:2332kBVmLib:47832kBVmPTE:1008kBVmSwap:0kBHugetlbPages:0kBCoreDumping:0Threads:4SigQ:1/15456SigPnd:0000000000000000ShdPnd:0000000000000000SigBlk:0000000000000000SigIgn:0000000004381??000SigCgt:00000001db816effCapInh:0000000000000000CapPrm:0000000000000000CapEff:0000000000000000CapBnd:0000003fffffffffCapAmb:0000000000000000NoNewPrivs:0Seccomp:0Cpus_allowed:3Cpus_allowed_list:0-1Mems_allowed:1Mems_allowed_list:0voluntary_ctxt_switches:12951nonvoluntary_ctxt_switches:21641其中比较有用的项有:TheVmDatadata部分的大小VmExetext部分的大小onVmHWM当前物理内存使用的最大值WmLckmlock锁定的内存大小VmLib共享库的大小UsageVmPTE页表大小VmPeak当前物理内存最大值VmRSS物理内存实际使用量VmSize逻辑地址大小VmStk栈大小VmSwap交换空间使用量