当下android这么火爆,你只需学一点java,拉出几个界面,再学学拍拍马屁,看到靠谱的项目假装虚心请教,原然偷偷摸摸的向老板汇报,整得像自己做的似的,也能赚几十K的工资。
如果你不会以上几招,那么深入理解linux虚拟内存管理,恭喜你,你是一个真正的程序员。接下来的这段文字,你有必要看下去,当然,只看一遍谁都看不懂,收藏以便日后再看,如果你压根就看不下去,那么没有关系,转发下,也能提高逼格。要知道,这是在中国仅仅只有十几个人搞得懂的linux虚拟内存模型 。
内存管理子系统是操作系统最重要的部分之一。从早期计算开始,系统的内存大小就难以
满足人们的需要。为了解决这个问题,可利用虚拟内存。虚拟内存通过当需要时在竞争的进
程之间共享内存,使系统显得有比实际上更多的内存空间。
虚拟内存不仅仅使机器上的内存变多,内存管理子系统还提供以下功能:
• 大地址空间操作系统使系统显得它有比实际上大得多的内存。虚拟内存可以比系统中
的物理内存大许多倍。
• 保护系统中每个进程有自己的虚拟地址空间。这些虚拟地址空间相互之间完全分离,
所以运行一个应用的进程不能影响其他的进程。同样,硬件的虚拟内存机制允许内存区
域被写保护。这样保护了代码和数据不被恶意应用重写。
• 内存映射内存映射用来把映像和数据文件映像到一个进程的地址空间。在内存映射中,
文件的内容被直接链接到进程的虚拟地址空间。
• 公平物理内存分配内存管理子系统给予系统中运行的每个进程公平的一份系统物理内
存。
• 共享虚拟内存尽管虚拟内存允许进程拥有分隔的(虚拟)地址空间,有时你会需要进程共
享内存。例如系统中可能会有几个进程运行命令解释shell bash。最好是在物理内存中只
有一份b a s h拷贝,所有运行b a s h的进程共享它;而不是有几份b a s h拷贝,每个进程虚拟
空间一个。动态库是另一个常见的几个进程共享执行代码的例子。
共享内存也可以被用作进程间通信( I P C )机制,两个或更多进程通过共有的内存交换信息。
L i n u x支持Unix(tm) System V的共享内存I P C。
虚拟内存抽象模型
在考察L i n u x支持虚拟内存所使用的方法之前,考察一下抽象模型会有所帮助。
当处理器运行一个程序时,它从内存中读取一条指令并解码。在解码该指令过程中它可
能需要取出或存放内存某个位置的内容。处理器然后执行该指令并移动到程序中下一条指令。
这样处理器总是访问内存来取指令或取存数据。
在虚拟内存系统中以上所有的地址都是虚拟地址而不是物理地址。处理器基于由操作系
统维护的一组表中的信息深入理解linux虚拟内存管理,将虚拟地址转换成物理地址。
为了使这种变换容易一些,虚拟内存和物理内存都被分为合适大小的块叫做“页( p a g e )”。
这些页都有同样的大小。它们可以不具有同样大小,但那样的话系统将很难管理。Alpha AXP
系统上L i n u x使用8 K B字节大小的页,Intel x86系统上使用4 K B字节大小的页。这些页中每一个
都有一个唯一的号码:页帧号(Page Frame Number, PFN)。在这种分页模型中,一个虚拟地址
由两部分组成:一个偏移和一个虚拟页帧号。如果页大小是4 K B字节,虚拟地址的11∶0位包含偏移,1 2位及高位是虚拟页帧号。每当处理器面临一个虚拟地址时,它必须析取出偏移和虚拟页帧号。处理器必须将虚拟页帧号转换成物理的页帧号,然后在该物理页中正确的偏移位置上进行访问。为了完成这些处理器要使用页表。
图 展示了两个进程的虚拟地址空间,进程X和进程Y,每个都有自己的页表。
这些页表将每个进程的虚拟页映射到内存中的物理页。图中显示进程X的虚拟页帧号0
映射到内存中物理页帧号1,进程Y的虚拟页帧号1映射到物理页帧号4。理论上的页表中每一
项包含下列信息:
• 有效标志,用来指示该页表项是否有效。
• 本项所描述的物理页帧号。
• 访问控制信息。它描述该页可以被怎样使用。它是否可以被写?是否包含可执行代码?
页表用虚拟页帧号作为偏移来访问。虚拟页帧号5将是表中第6个元素( 0是第1个)。
为了将一个虚拟地址转换成物理地址,处理器首先必须得到虚拟地址页帧号和在该虚拟页中的偏移。通过选取页大小为2的幂,这可以很容易地屏蔽和移位得到。再看一下图
设页大小是0 x 2 0 0 0字节(即十进制8 1 9 2 ),Y进程虚拟地址空间中一个地址为0 x 2 1 9 4,则处理器
将把该地址转换为虚拟页帧号1的偏移0 x 1 9 4。
处理器使用虚拟页帧号作为进程页表的索引来检索它的页表项。如果该偏移处页表项有
效,处理器将从该项取出物理页帧号。如果该页表项无效,说明处理器访问了虚拟内存中不
存在的区域。在这种情况下,处理器不能解析该地址linux运维最佳实践,并且必须把控制传给操作系统来解决
问题。
处理器如何通知操作系统一个正确的进程试图访问一个没有有效转换的虚拟地址,这是
依处理器不同而不同的。无论如何处理器能够处理它,这被称作“页故障(page fault)”。操作
系统被告知故障的虚拟地址和故障原因。
如果访问的是有效的页表项,处理器取出物理页帧号,并将它乘以页的大小以得到物理
内存中该页的基地址。最后,处理器将偏移加到所需的指令或数据的地址。
再以上面的例子为例,进程Y的虚拟页帧号1映射到物理页帧号4,起始于0 x 8 0 0 0 ( 4×
0 x 2 0 0 0 )。加上0 x 1 9 4字节的偏移,最后得到物理地址0 x 8 1 9 4。
通过用这种方式映射虚拟地址和物理地址,虚拟内存能够以任何次序被映射到系统物理
页。例如,在图1 - 2 - 1中进程X的虚拟页帧号0被映射到物理页帧号1,而虚拟页帧号7被映射到
物理页帧号0linux系统下载,尽管在虚拟内存中它比虚拟页帧号0要高。这说明了虚拟内存的一个有趣的副
作用:虚拟内存页不必以任何特定次序出现在物理内存中。
引:
Memory allocation inside the kernel is not as easy as memory allocation outside the kernel. Many factors contribute to this. Primarily, the
kernel simply lacks the luxuries enjoyed by user-space. Unlike user-space, the kernel is not always afforded the capability to easily
allocate memory. For example, often the kernel cannot sleep and the kernel cannot easily deal with memory errors. Because of these
limitations, and the need for a lightweight memory allocation scheme, getting hold of memory in the kernel is more complicated than in
user-space. This is not to say that kernel memory allocations are difficult, however, as you'll see. Just different.
This chapter discusses the methods used to obtain memory inside the kernel. Before you can delve into the actual allocation interfaces,
however, you need to understand how the kernel handles memory.
~~~~~~~~~~~~~~~~~~~
更多精彩,请访问我们的网站:我爱狄八哥( ) 我爱狄八哥,华语地区最大的技术类垂直社区52debug。net