mlock家族:锁定物理内存

mlock家族:锁定物理内存

系统调用 mlock 家族容许程序在物理内存上锁住它的部分或所有地址空间。这将阻止Linux 将这个内存页调度到交换空间(swap space),即便该程序已有一段时间没有访问这段空间。安全

一个严格时间相关的程序可能会但愿锁住物理内存,由于内存页面调出调入的时间延迟可能太长或过于不可预知。安全性要求较高的应用程序可能但愿防止敏感数据被换出到交换文件中,由于这样在程序结束后,攻击者可能从交换文件中恢复出这些数据。app

锁定一个内存区间只需简单将指向区间开始的指针及区间长度做为参数调用 mlockLinux 分配内存到页(page)且每次只能锁定整页内存,被指定的区间涉及到的每一个内存页都将被锁定。getpagesize 函数返回系统的分页大小,在 x86 Linux 系统上,这个值是 4KB。ide

举个例子来讲,分配 32Mb 的地址空间并把它锁进内存中,您须要使用以下的代码:函数

const int alloc_size = 32 * 1024 * 1024;
char* memory = malloc (alloc_size);
mlock (memory, alloc_size);

需注意的是,仅分配内存并调用 mlock 并不会为调用进程锁定这些内存,由于对应的分页多是写时复制(copy-on-write)5。所以,你应该在每一个页面中写入一个假的值:spa

size_t i;
size_t page_size = getpagesize ();
for (i = 0; i < alloc_size; i += page_size)
  memory[i] = 0;

这样针对每一个内存分页的写入操做会强制 Linux 为当前进程分配一个独立、私有的内存页。.net

要解除锁定,能够用一样的参数调用 munlock。指针

若是你但愿程序的所有地址空间被锁定在物理内存中,请用 mlockall。这个系统调用接受一个参数;若是指定 MCL_CURRENT,则仅仅当前已分配的内存会被锁定,以后分配的内存则不会;MCL_FUTURE 则会锁定以后分配的全部内存。使用 MCL_CURRENT|MCL_FUTURE 将已经及未来分配的全部内存锁定在物理内存中。进程

锁定大量的内存,尤为是经过 mlockall,对整个系统而言多是危险的。不加选择的内存加锁会把您的系统折磨到死机,由于其他进程被迫争夺更少的资源的使用权,而且会更快地被交换进出物理内存(这被称之为 thrashing)。若是你锁定了太多的内存,Linux 系统将总体缺少必需的内存空间并开始杀死进程。ip

出于这个缘由,只有具备超级用户权限的进程才能利用 mlock 或 mlockall 锁定内存。若是一个并没有超级用户权限的进程调用了这些系统调用将会失败、获得返回值 -1 并获得 errno 错误号 EPERM。内存

munlock 系统调用会将当前进程锁定的全部内存解锁,包括经由 mlock 或 mlockall 锁定的全部区间。

一个监视程序内存使用状况的方便方法是使用top命令。在top的输出中,SIZE显示了每一个程序的虚地址空间的大小(您的整个程序代码、数据、栈,其中 一些应该已被交换出到交换区间)。RSS 列(Resident set size,持久集合大小)显示了程序所占用的的物理内存大小。全部当前运行程序的 RSS 数值总和不会超过您的计算机物理内存大小,而且全部地址空间的大小限制值为2GB(对于32字节版本的Linux来讲)

若是您使用了mlock系统调用,请引入<sys.nman.h>头文件。

5 Copy-on-write 写时复制意味着仅当进程在内存区间的任意位置写入内容时,Linux 系统才会为进程建立该区内存的私有副本。

相关文章
相关标签/搜索