linux 内存 分配?linux进程最大内存限制
各位老铁们好,相信很多人对linux 内存 分配都不是特别的了解,因此呢,今天就来为大家分享下关于linux 内存 分配以及linux进程最大内存限制的问题知识,还望可以帮助大家,解决大家的一些困惑,下面一起来看看吧!
超详细|Linux 如何进行内存分配
Linux操作系统中的虚拟内存管理分为内核空间和用户空间两大部分。在32位和64位系统中,地址空间范围不同,每个进程拥有独立的虚拟内存,内核地址关联相同物理内存,便于进程切换至内核态访问。用户空间内存分布,以32位系统为例,从低到高分为6种不同的内存段。
申请内存空间通常有两种方式:malloc和mmap。使用malloc时,系统可能调用brk或mmap函数。当分配小型内存(小于或等于128kb),malloc会通过brk函数移动堆顶指针获取新空间;分配大型内存(大于128kb)时,mmap通过私有匿名映射在文件映射区分配内存。
malloc分配的是虚拟内存,未被访问的虚拟内存不会映射到物理内存,不占用物理内存资源。访问已分配虚拟地址空间时,操作系统通过查找页表建立虚拟内存与物理内存映射关系。缺页中断发生在虚拟内存不在主存时,系统将文件映射为分页交换文件。
分配内存后使用free释放内存,malloc通过brk系统调用在堆空间预分配内存,内存释放缓存在内存池,下次申请时直接取用,减少了系统调用和缺页中断次数,降低CPU消耗。相反,使用mmap分配内存每次释放时归还给操作系统,频繁使用mmap分配内存会导致CPU消耗较大,且增加运行态切换和缺页中断次数。
通过brk分配内存时,连续申请并释放大块内存后,堆内可能产生不可用的碎片,导致内存泄露。随着频繁的malloc和free操作,尤其是对小块内存的使用,系统内将累积越来越多不可用的碎片,引发“内存泄露”问题,这种现象在使用valgrind时无法检测。因此,malloc默认分配大块内存(128KB)时使用mmap分配空间,以优化内存管理。
linux共享内存的分配
进程通过调用shmget(Shared Memory GET,获取共享内存)来分配一个共享内存块。
该函数的第一个参数是一个用来标识共享内存块的键值。彼此无关的进程可以通过指定同一个键以获取对同一个共享内存块的访问。不幸的是,其它程序也可能挑选了同样的特定值作为自己分配共享内存的键值,从而产生冲突。用特殊常量IPC_PRIVATE作为键值可以保证系统建立一个全新的共享内存块。
该函数的第二个参数指定了所申请的内存块的大小。因为这些内存块是以页面为单位进行分配的,实际分配的内存块大小将被扩大到页面大小的整数倍。
第三个参数是一组标志,通过特定常量的按位或操作来shmget。这些特定常量包括:
IPC_CREAT:这个标志表示应创建一个新的共享内存块。通过指定这个标志,我们可以创建一个具有指定键值的新共享内存块。
IPC_EXCL:这个标志只能与 IPC_CREAT同时使用。当指定这个标志的时候,如果已有一个具有这个键值的共享内存块存在,则shmget会调用失败。也就是说,这个标志将使线程获得一个“独有”的共享内存块。如果没有指定这个标志而系统中存在一个具有相同键值的共享内存块,shmget会返回这个已经建立的共享内存块,而不是重新创建一个。
模式标志:这个值由9个位组成,分别表示属主、属组和其它用户对该内存块的访问权限。其中表示执行权限的位将被忽略。指明访问权限的一个简单办法是利用<sys/stat.h>中指定,并且在手册页第二节stat条目中说明了的常量指定。例如,S_IRUSR和S_IWUSR分别指定了该内存块属主的读写权限,而 S_IROTH和S_IWOTH则指定了其它用户的读写权限。下面例子中shmget函数创建了一个新的共享内存块(当shm_key已被占用时则获取对一个已经存在共享内存块的访问),且只有属主对该内存块具有读写权限,其它用户不可读写。
int segment_id= shmget(shm_key, getpagesize(), IPC_CREAT| S_IRUSR| S_IWUSR);如果调用成功,shmget将返回一个共享内存标识符。如果该共享内存块已经存在,系统会检查访问权限,同时会检查该内存块是否被标记为等待摧毁状态。
linux共享内存分配
在Linux系统中,进程通过调用 shmget(共享内存获取)函数来申请一块可以供多个进程共享的内存区域。这个函数的使用需要三个关键参数。
首先,第一个参数是一个唯一的键值,用于标识共享内存。为了创建一个独占的内存块,进程可以使用IPC_PRIVATE常量作为键值。然而,如果其他进程也选择相同的键值,可能会导致冲突。通过指定一个已存在的键值,进程可以访问已存在的共享内存块,前提是权限允许。
第二个参数是所请求内存的大小。系统会以页面大小为单位进行分配,所以实际分配的内存大小会是页面大小的整数倍。这意味着,即使请求的大小不是页面的整数倍,也会向上取整分配。
第三个参数是一组标志,通过按位或操作来控制共享内存的行为。IPC_CREAT标志用于创建新的共享内存块,如果键值已被占用,只有当同时使用IPC_EXCL标志时,函数才会失败并拒绝创建。IPC_EXCL可以确保进程获得的是一个独占的内存块,而非共享现有资源。
权限控制由模式标志(通常由S_IRUSR, S_IWUSR, S_IROTH, S_IWOTH等常量组合)完成,这些标志决定了属主、属组和其他用户对内存块的访问权限。例如,S_IRUSR和S_IWUSR允许属主读写,S_IROTH和S_IWOTH则允许其他用户只读或只写。在创建共享内存时,可以设置这些标志来限制访问权限。
如果shmget调用成功,它会返回一个标识符,用于后续对共享内存的操作。如果内存块已存在,系统会检查权限和销毁标记。这样,进程就能有效地管理和共享内存资源。