iis服务器助手广告广告
返回顶部
首页 > 资讯 > 操作系统 >Linux中怎么实现虚拟内存
  • 191
分享到

Linux中怎么实现虚拟内存

2024-04-02 19:04:59 191人浏览 安东尼
摘要

这期内容当中小编将会给大家带来有关linux中怎么实现虚拟内存,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。  Linux虚拟内存怎么实现  第一个例子:下面一段程序会打

这期内容当中小编将会给大家带来有关linux中怎么实现虚拟内存,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。

  Linux虚拟内存怎么实现

  第一个例子:下面一段程序会打印出程序的pid(进程号)后挂起。

  #include

  #include

  #include

  intmain(){

  printf("run`pmap%d`\n",getpid());

  pause();

  }

  将上面代码保存成文件mem_munch.c然后运行下面程序编译并执行:

  $GCcmem_munch.c-omem_munch

  $./mem_munch

  run`pmap25681`

  上面进程号是25681,可能你试验的结果会不太一样。

  下面我们通过pmap命令来查看一下这个小程序的内存使用情况

  $pmap25681

  25681:./mem_munch

  00000000004000004Kr-x--/home/user/mem_munch

  00000000006000004Kr----/home/user/mem_munch

  00000000006010004Krw---/home/user/mem_munch

  00007fcf5af880001576Kr-x--/lib/x86_64-linux-gnu/libc-2.13.so

  00007fcf5b1120002044K-----/lib/x86_64-linux-gnu/libc-2.13.so

  00007fcf5b31100016Kr----/lib/x86_64-linux-gnu/libc-2.13.so

  00007fcf5b3150004Krw---/lib/x86_64-linux-gnu/libc-2.13.so

  00007fcf5b31600024Krw---[anon]

  00007fcf5b31c000132Kr-x--/lib/x86_64-linux-gnu/ld-2.13.so

  00007fcf5b51200012Krw---[anon]

  00007fcf5b53900012Krw---[anon]

  00007fcf5b53c0004Kr----/lib/x86_64-linux-gnu/ld-2.13.so

  00007fcf5b53D0008Krw---/lib/x86_64-linux-gnu/ld-2.13.so

  00007fff7efd8000132Krw---[stack]

  00007fff7efff0004Kr-x--[anon]

  ffffffffff6000004Kr-x--[anon]

  total3984K

  上面的结果是这个程序的内存使用情况,其实更确切的说是这个程序认为它使用内存的情况。从上面的结果我们能看到,当你访问libc库时,实际上是对内存地址00007fcf5af88000的访问,当你访问ld库时,实际上是对内存地址00007fcf5b31c000的访问。

  上面的输出可能还比较抽象,下面我们修改一下上面的程序,我们在程序的堆和栈上各放一块数据。

  #include

  #include

  #include

  #include

  intmain(){

  inton_stack,*on_heap;

  //局部变量是放在栈上的,所以on_stack的地址就是栈的初始地址

  on_stack=42;

  printf("stackaddress:%p\n",&on_stack);

  //malloc的内存是在堆上分配的

  on_heap=(int*)malloc(sizeof(int));

  printf("heapaddress:%p\n",on_heap);

  printf("run`pmap%d`\n",getpid());

  pause();

  }

  编译运行:

  $./mem_munch

  stackaddress:0x7fff497670bc

  heapaddress:0x1b84010

  run`pmap11972`

  然后再用pmap命令查看一下内存使用:

  $pmap11972

  11972:./mem_munch

  00000000004000004Kr-x--/home/user/mem_munch

  00000000006000004Kr----/home/user/mem_munch

  00000000006010004Krw---/home/user/mem_munch

  0000000001b84000132Krw---[anon]

  00007f3ec4d980001576Kr-x--/lib/x86_64-linux-gnu/libc-2.13.so

  00007f3ec4f220002044K-----/lib/x86_64-linux-gnu/libc-2.13.so

  00007f3ec512100016Kr----/lib/x86_64-linux-gnu/libc-2.13.so

  00007f3ec51250004Krw---/lib/x86_64-linux-gnu/libc-2.13.so

  00007f3ec512600024Krw---[anon]

  00007f3ec512c000132Kr-x--/lib/x86_64-linux-gnu/ld-2.13.so

  00007f3ec532200012Krw---[anon]

  00007f3ec534900012Krw---[anon]

  00007f3ec534c0004Kr----/lib/x86_64-linux-gnu/ld-2.13.so

  00007f3ec534d0008Krw---/lib/x86_64-linux-gnu/ld-2.13.so

  00007fff49747000132Krw---[stack]

  00007fff497bb0004Kr-x--[anon]

  ffffffffff6000004Kr-x--[anon]

  total4116K

  这次多出了上面红色的一行内容,红色内容就是堆的起始位置:

  0000000001b84000132Krw---[anon]

  在我们程序运行的输出里也有一行红色的输出,这是这个地址在程序中的内存地址:

  heapaddress:0x1b84010

  这两个地址基本上是一样的,其中的anon是Anonymous的缩写,表明这段内存是没有文件映射的。

  我们再看上面绿色的两行,与上面相对应,这两行分别是用pmap和应用程序看到的栈起始地址:

  00007fff49747000132Krw---[stack]

  stackaddress:0x7fff497670bc

  上面说到的内存使用,都只是程序认为自己对内存的使用,实际上程序在分配内存是不知道系统内存的状态的。所以上面的输出都只是从程序自己的角度看到的内存使用状况。比如在上面的例子中,我们看到程序的内存地址空间是从0×0000000000400000到0xffffffffff600000的所有地址(而0xffffffffff600000到0×00007fffffffffffffff之间的地址是有特殊用处的,这里不多讲)。这样算下来,我们总共可以使用的内存空间有1千万TB。

  但是实际上目前没有硬件能有1千万TB的物理内存。为什么操作系统会如此设计呢?原因有很多,可以看这里,但也正因此,我们可以使用远远超出物理内存大小的内存空间。

  内存映射

  内存映射的原理就是让操作系统将一个文件映射到一段内存中,然后在操作这个文件内存就可以像操作内存一样。比如我们创建一个完全内容随机的文件,然后将它用内存映射的方式映射到一段内存空间中。那么我们在这段内存中随便取一位就相当于取到了一个随机数。下面就让我们来做这个实验,先用下面命令生成一个内容随机的文件。

  $ddif=/dev/urandombs=1024count=1000000of=/home/user/random

  1000000+0recordsin

  1000000+0recordsout

  1024000000bytes(1.0GB)copied,123.293s,8.3MB/s

  $ls-lhrandom

  -rw-r--r--1useruser977M2011-08-2916:46random

  然后我们用下面程序来将这个文件内容映射到内存,再从中取出随机数

  #include

  #include

  #include

  #include

  #include

  intmain(){

  char*random_bytes;

  FILE*f;

  intoffset=0;

  //open"random"forreading

  f=fopen("/home/user/random","r");

  if(!f){

  perror("couldn'topenfile");

  return-1;

  }

  //wewanttoinspectmemorybeforemappingthefile

  printf("run`pmap%d`,thenpress",getpid());

  getchar();

  random_bytes=mmap(0,1000000000,PROT_READ,MAP_SHARED,fileno(f),0);

  if(random_bytes==MAP_FAILED){

  perror("errORMappingthefile");

  return-1;

  }

  while(1){

  printf("randomnumber:%d(pressfornextnumber)",*(int*)(random_bytes+offset));

  getchar();

  offset+=4;

  }

  }

  然后运行这个程序:

  $./mem_munch

  run`pmap12727`,thenpress

  Linux虚拟内存怎么实现

  下面我们通过一次次的按下回车键来从这个文件中读取随机数,按下几次后我们可以再通过pmap来查看其内存空间的情况:

  $pmap12727

  12727:./mem_munch

  00000000004000004Kr-x--/home/user/mem_munch

  00000000006000004Kr----/home/user/mem_munch

  00000000006010004Krw---/home/user/mem_munch

  000000000147d000132Krw---[anon]

  00007fe261c6f000976564Kr--s-/home/user/random

  00007fe29d61c0001576Kr-x--/lib/x86_64-linux-gnu/libc-2.13.so

  00007fe29d7a60002044K-----/lib/x86_64-linux-gnu/libc-2.13.so

  00007fe29d9a500016Kr----/lib/x86_64-linux-gnu/libc-2.13.so

  00007fe29d9a90004Krw---/lib/x86_64-linux-gnu/libc-2.13.so

  00007fe29d9aa00024Krw---[anon]

  00007fe29d9b0000132Kr-x--/lib/x86_64-linux-gnu/ld-2.13.so

  00007fe29dba600012Krw---[anon]

  00007fe29dbcc00016Krw---[anon]

  00007fe29dbd00004Kr----/lib/x86_64-linux-gnu/ld-2.13.so

  00007fe29dbd10008Krw---/lib/x86_64-linux-gnu/ld-2.13.so

  00007ffff29b2000132Krw---[stack]

  00007ffff29de0004Kr-x--[anon]

  ffffffffff6000004Kr-x--[anon]

  total980684K

  上面的输出和之前的大同小异,但是多出了上面红色的一行。这是我们上面的随机文件映射到内存中的内存。我们再使用pmap-x选项来查看一下程序的内存使用,会得到下面的内容,其中RSS(residentsetsize)列表示真实占用的内存。

  pmap-x12727

  12727:./mem_munch

  AddressKbytesRSSDirtyModeMapping

  0000000000400000040r-x--mem_munch

  0000000000600000044r----mem_munch

  0000000000601000044rw---mem_munch

  000000000147d000044rw---[anon]

  00007fe261c6f000040r--s-random

  00007fe29d61c00002880r-x--libc-2.13.so

  00007fe29d7a6000000-----libc-2.13.so

  00007fe29d9a500001616r----libc-2.13.so

  00007fe29d9a9000044rw---libc-2.13.so

  00007fe29d9aa00001616rw---[anon]

  00007fe29d9b000001080r-x--ld-2.13.so

  00007fe29dba600001212rw---[anon]

  00007fe29dbcc00001616rw---[anon]

  00007fe29dbd0000044r----ld-2.13.so

  00007fe29dbd1000088rw---ld-2.13.so

  00007ffff29b200001212rw---[stack]

  00007ffff29de000040r-x--[anon]

  ffffffffff600000000r-x--[anon]

  ----------------------------------

  totalkB980684508100

  如果你的虚拟内存占用(上面的Kbytes列)都是0,不用担心,这是一个在Debian/ubuntu系统上pmap-x命令的bug。最后一行输出的总占用量是正确的。

  现在你可以看一下RSS那一列,这就是实际内存占用。在random文件上,你的程序实际上可以访问在00007fe261c6f000之前的数十亿字节的内存地址,但是只要你访问的地址超过4KB,那么操作系统就会去磁盘上查找内容。也就是说实际上只有4KB的物理内存被使用了。只有访问这4KB的东西时,才是真正的内存操作。其它部分虽然你使用的也是内存操作函数来访问它,但是由于它没有被加载到内存中,所以在这些内容被访问的时候,操作系统会先去磁盘读random中读取内容到内存中。

  如果我们把程序再修改一下,修改成下面这样,让程序把整个random文件都访问一遍。

  #include

  #include

  #include

  #include

  #include

  intmain(){

  char*random_bytes;

  FILE*f;

  intoffset=0;

  //open"random"forreading

  f=fopen("/home/user/random","r");

  if(!f){

  perror("couldn'topenfile");

  return-1;

  }

  random_bytes=mmap(0,1000000000,PROT_READ,MAP_SHARED,fileno(f),0);

  if(random_bytes==MAP_FAILED){

  printf("errormappingthefile\n");

  return-1;

  }

  for(offset=0;offset<1000000000;offset+=4){   inti=*(int*)(random_bytes+offset);   //toshowwe'remakingprogress   if(offset%1000000==0){   printf(".");   }   }   //attheend,waitforsignalsowecancheckmem   printf("\ndone,run`pmap-x%d`\n",getpid());   pause();   }   现在我们的pmap-x命令就会得到如下输出:   $pmap-x5378   5378:./mem_munch   AddressKbytesRSSDirtyModeMapping   0000000000400000044r-x--mem_munch   0000000000600000044r----mem_munch   0000000000601000044rw---mem_munch   0000000002271000044rw---[anon]   00007fc2aa33300009765640r--s-random   00007fc2e5ce000002920r-x--libc-2.13.so   00007fc2e5e6a000000-----libc-2.13.so   00007fc2e606900001616r----libc-2.13.so   00007fc2e606d000044rw---libc-2.13.so   00007fc2e606e00001616rw---[anon]   00007fc2e607400001080r-x--ld-2.13.so   00007fc2e626a00001212rw---[anon]   00007fc2e629000001616rw---[anon]   00007fc2e6294000044r----ld-2.13.so   00007fc2e6295000088rw---ld-2.13.so   00007fff037e600001212rw---[stack]   00007fff039c9000040r-x--[anon]   ffffffffff600000000r-x--[anon]   ----------------------------------   totalkB980684977072104   

上述就是小编为大家分享的Linux中怎么实现虚拟内存了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注编程网操作系统频道。

--结束END--

本文标题: Linux中怎么实现虚拟内存

本文链接: https://www.lsjlt.com/news/56123.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Linux中怎么实现虚拟内存
    这期内容当中小编将会给大家带来有关Linux中怎么实现虚拟内存,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。  Linux虚拟内存怎么实现  第一个例子:下面一段程序会打...
    99+
    2022-10-18
  • linux如何实现虚拟内存
    今天小编给大家分享一下linux如何实现虚拟内存的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。虚拟内存的实现需要建立在离散分...
    99+
    2023-07-04
  • linux怎么扩展虚拟内存
    本篇内容主要讲解“linux怎么扩展虚拟内存”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“linux怎么扩展虚拟内存”吧!在linux磁盘刚分区的时候,我们会划分一个swap分区,这块分区作为一...
    99+
    2023-06-10
  • linux中虚拟内存是什么
    这篇文章主要为大家展示了“linux中虚拟内存是什么”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“linux中虚拟内存是什么”这篇文章吧。1. 讨论虚拟内存前的热身我们需要知道的是计算机对内存分...
    99+
    2023-06-15
  • Linux虚拟内存是什么
    这篇“Linux虚拟内存是什么”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Linux虚拟内存是什么”文章吧。虚拟内存由来毋...
    99+
    2023-06-27
  • Linux虚拟内存不够用怎么办
    这篇文章主要讲解了“Linux虚拟内存不够用怎么办”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Linux虚拟内存不够用怎么办”吧!解决方法:1、建立swapfile:2、格式化为swap格...
    99+
    2023-06-28
  • 虚拟主机linux内存不足怎么解决
    虚拟主机的内存不足可能是由于网站访问量增加或者应用程序占用内存过多导致的。解决方法如下:1. 优化网站,减少资源占用。可以通过压缩图...
    99+
    2023-06-05
    虚拟主机linux 虚拟主机 linux
  • mySQL中怎么优化虚拟内存
    这篇文章给大家介绍mySQL中怎么优化虚拟内存,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。 更改后如下: innodb_buffer_pool_size=576M ->25...
    99+
    2022-10-18
  • win10中怎么设置虚拟内存
    在win10中设置虚拟内存的方法:1.右键此电脑选择属性;2.点击高级系统设置;3.点击性能设置;4.点击更改虚拟内存;5.设置虚拟内存大小,并确认;具体步骤如下:首先,在win10系统桌面中右键点击“此电脑”选择“属性”选项;进入系统页面...
    99+
    2022-10-20
  • Linux虚拟内存地址怎么转化成物理内存地址
    这篇文章主要讲解了“Linux虚拟内存地址怎么转化成物理内存地址”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Linux虚拟内存地址怎么转化成物理内存地址”吧!背景现代手机这种SOC(sys...
    99+
    2023-06-16
  • linux中虚拟内存的示例分析
    这篇文章给大家分享的是有关linux中虚拟内存的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。什么是虚存为什么需要它?   我们知道程序代码和数据必须驻留在内存中才能得以运行,然而系统内存数量很有限,往往...
    99+
    2023-06-13
  • linux的虚拟内存机制是什么
    这篇“linux的虚拟内存机制是什么”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“linux的虚拟内存机制是什么”文章吧。l...
    99+
    2023-07-01
  • win7虚拟内存大小和虚拟内存的位置怎么修改?
    现在很多人都开始用Windows7操作系统了,但是很多人的电脑还没有更新配置,运行win7系统有点吃力,设置合适的虚拟内存可以让我们的电脑速度快一点,WIN7系统默认的虚拟内存是在C盘系统盘上,可能会影响我们电脑的速度!...
    99+
    2023-06-16
    win7更改虚拟内存位置 win7设置虚拟内存大小 win7虚拟内存初始 虚拟内存 位置 win7 大小
  • Linux云服务器怎么设置swap虚拟内存
    本篇内容介绍了“Linux云服务器怎么设置swap虚拟内存”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!swap交换内存主要是指当物理内存不...
    99+
    2023-07-06
  • ubuntu虚拟内存怎么清空
    本篇内容主要讲解“ubuntu虚拟内存怎么清空”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“ubuntu虚拟内存怎么清空”吧!ubuntu清空虚拟内存的方法:打开Ubuntu系统,进入终端命令行...
    99+
    2023-07-04
  • Win11怎么设置虚拟内存
    在Windows 11中设置虚拟内存的方法如下:1. 打开“控制面板”,可以在开始菜单中搜索或右键点击任务栏上的“开始”按钮,然后选...
    99+
    2023-08-22
    Win11
  • win10怎么扩大虚拟内存
    要扩大Windows 10的虚拟内存,可以按照以下步骤操作:1. 打开“控制面板”,可以通过在Windows搜索栏中输入“控制面板”...
    99+
    2023-09-12
    win10
  • win10怎么增加虚拟内存
    要增加Windows 10的虚拟内存,可以按照以下步骤进行操作:1. 打开“控制面板”:可以通过在开始菜单中搜索“控制面板”来找到。...
    99+
    2023-09-12
    win10
  • win8怎么设置虚拟内存
    这篇文章主要介绍了win8怎么设置虚拟内存的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇win8怎么设置虚拟内存文章都会有所收获,下面我们一起来看看吧。设置方法:进入【系统属性】后点击【高级系统设置】,点击【高...
    99+
    2023-06-28
  • win11虚拟内存怎么设置
    这篇“win11虚拟内存怎么设置”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“win11虚拟内存怎么设置”文章吧。设置方法:...
    99+
    2023-07-01
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作