linux虚拟地址物理地址
❶ linux 虚拟地址,到底怎么理解
不是仅仅 Linux 是这么设计的,整个现代流行的操作系统都是这么设计的。
应用程序被读入内存后,为了保证系统的统一性,所有的程序都有同样的一套寻址规范。这个寻址就是虚拟地址。这个虚拟地址是系统提供转换的,不是程序的工作。
如果系统不提供这个功能,那么应用程序就需要自己去寻找没有被使用的内存,以及还要自己去处理内存容量的问题,而且如果程序调用外部的一些函数库,这些函数库也需要分配内存,这会导致应用程序的设计难度非常大,每个应用程序实际上就是一个操作系统了。多个程序共同运行导致内存使用混乱也很容易出现。
应用程序申请内存,使用的是操作系统的内存分配功能。这样操作系统可以根据实际情况给应用程序内存,程序不需要考虑因为内存位置不同而必须不同编写的难度。而且操作系统还可以提供虚拟内存等等各种方式来扩充内存,这样的内存对于应用程序来说是不需要考虑的,一切都有系统打理。
使用虚拟地址后,对于应用程序来说,他的内存使用不需要考虑其他的程序占用,也不需要考虑内存容量的问题,也不需要考虑内存块位置,函数库的调用也都扔给操作系统打理。这使得应用程序不需要考虑具体如何管理内存,只需要考虑作为应用程序的应用部分。
而且,因为内存是虚拟的,应用程序一些函数调用,操作系统可以把多个应用程序的调用都用同一套数据来处理,这样,既可以节约内存使用(就是启动100个应用程序,也只需要内存里有一套函数库而已),也可以做到外部函数库和应用程序没有直接关联,纯粹是由系统做虚拟地址过渡。
至于为什么 4G ,这是传统+一些兼容的考虑。
以前没有这个技术时,每个程序都可以完全使用整个系统,整个空间是连续的。到了这种虚拟地址的方式后,每个程序还是有自己“独立”的一整套内存地址。但每个程序内存使用量肯定不一样。那么多少内存空间才完全够用呢?当时因为正好使用了 32 位系统。那么就把整个 32 位环境支持的 4G 内存容量作为这个极限。
不过因为内存地址是虚拟的。实际应用程序要用内存,是需要先申请的,所以只有程序申请后,真实内存才会被占用。这个 4G 只是在算法上作为极限。
不过因为 4G 也是硬件极限。所以 4G 以外的地址都是不能使用的,这就导致另一个问题,一些硬件有存储器,有些硬件需要存储空间做交互(比如 PCI ,比如各种硬件,比如 AGP 显卡)。这些存储区域怎么处理?
所以,Windows Vista 的 32 位版在 4G 内存的机器上曾经报出只有 3.5G (有的机器甚至只有 3.25G 可以用)。就是这个问题的解决办法导致的:把硬件的内存用虚拟地址的方式,放到虚拟地址的最后面。这样应用程序调用硬件存储时,可以直接按照内存的方式读写。这样应用程序就很好的统一了存储界面:只有 4G 的内存范围,不存在其他方式的存储调用方式(硬盘需要用读写功能读取到内存后才能处理,而不是直接进行处理)。这样应用程序的开发就很简单,而且整个内存的使用每个程序都一样。不存在各种硬件的原因而不同导致的需要重新设计内存管理算法。操作系统也能根据实际应用程序的需要随时分配数据,也可以根据每个程序的运行情况,区别的提供物理内存或者虚拟的内存。
这么设计最大的一个好处是,硬件环境和应用程序是无关的,中间由操作系统做转换。而且应用程序互相之间也没有影响,就好象整个内存都由他自己一个程序使用一样。
PS:说了半天,我发现我自己也说不清楚其中的缘由……
❷ linux kvm虚拟机求救多个虚拟机无法通信
你克隆后,这四个虚拟机拥有相同的MAC地址而导致的。
解决方法:
删除 /etc/udev/rules.d/70-persistent-net.rules
命令: rm -fr /etc/udev/rules.d/70-persistent-net.rules
将/etc/sysconfig/network-scripts/ifcfg-eth0中的MAC地址用#注释掉
重启机器。
若有问题,给我留言。
❸ Linux 内核的内存管理 - 概念
Concepts overview — The Linux Kernel documentation
Linux中的内存管理是一个复杂的系统,经过多年的发展,它包含越来越多的功能,以支持从 MMU-less microcontrollers 到 supercomputers 的各种系统。
没有MMU内存管理的系统被称为 nommu ,它值得写一份专门的文档进行描述。
尽管有些概念是相同的,这里我们假设MMU可用,CPU可以将虚拟地址转换为物理地址。
计算机系统中的物理内存是有限资源,即便支持内存热插拔,其可以安装的内存也有限的。物理内存不一定必须是连续的;它可以作为一组不同的地址范围被访问。此外,不同的CPU架构,甚至同架构的不同实现对如何定义这些地址范围都是不同的。
这使得直接处理物理内存异常复杂,为了避免这种复杂性,开发了 虚拟内存 (virtual memory) 的概念。
虚拟内存从应用软件中抽象出物理内存的细节,只允许在物理内存中保留需要的信息 (demand paging) ,并提供一种机制来保护和控制进程之间的数据共享。
通过虚拟内存,每次内存访问都访问一个 虚拟地址 。当CPU对从系统内存读取(或写入)的指令进行解码时,它将该指令中编码的虚拟地址转换为内存控制器可以理解的物理地址。
物理内存被切分为 页帧 page frames 或 页 pages 。页的大小是基于架构的。一些架构允许从几个支持的值中选择页大小;此选择在内核编译时设置到内核配置。
每个物理内存页都可以映射为一个或多个 虚拟页(virtual pages) 。映射关系描述在 页表(page tables) 中,页表将程序使用的虚拟地址转换为物理内存地址。页表以层次结构组织。
最底层的表包含软件使用的实际内存页的物理地址。较高层的表包含较低层表页的物理地址。顶层表的指针驻留在寄存器中。
当CPU进行地址转换的时候,它使用寄存器访问顶级页表。
虚拟地址的高位,用于顶级页表的条目索引。然后,通过该条目访问下级,下级的虚拟地址位又作为其下下级页表的索引。虚拟地址的最低位定义实际页内的偏移量。
地址转换需要多次内存访问,而内存访问相对于CPU速度来说比较慢。为了避免在地址转换上花费宝贵的处理器周期,CPU维护着一个称为 TLB (Translation Lookaside Buffer)的用于地址转换缓存(cache)。通常TLB是非常稀缺的资源,需要大内存工作应用程序会因为TLB未命中而影响性能。
很多现代CPU架构允许页表的高层直接映射到内存页。例如,x86架构,可以通过二级、三级页表的条目映射2M甚至1G内存页。在Linux中,这些内存页称为 大页 (Huge) 。大页的使用显着降低了TLB的压力,提高了TLB命中率,从而提高了系统的整体性能。
Linux提供两种机制开启使用大页映射物理内存。
第一个是 HugeTLB 文件系统,即 hugetlbfs 。它是一个伪文件系统,使用RAM作为其存储。在此文件系统中创建的文件,数据驻留在内存中,并使用大页进行映射。
关于 HugeTLB Pages
另一个被称为 THP (Transparent HugePages) ,后出的开启大页映射物理内存的机制。
与 hugetlbfs 不同,hugetlbfs要求用户和/或系统管理员配置系统内存的哪些部分应该并可以被大页映射;THP透明地管理这些映射并获取名称。
关于 Transparent Hugepage Support
通常,硬件对不同物理内存范围的访问方式有所限制。某些情况下,设备不能对所有可寻址内存执行DMA。在其他情况下,物理内存的大小超过虚拟内存的最大可寻址大小,需要采取特殊措施来访问部分内存。还有些情况,物理内存的尺寸超过了虚拟内存的最大可寻址尺寸,需要采取特殊措施来访问部分内存。
Linux根据内存页的使用情况,将其组合为多个 zones 。比如, ZONE_DMA 包含设备用于DMA的内存, ZONE_HIGHMEM 包含未永久映射到内核地址空间的内存, ZONE_NORMAL 包含正常寻址内存页。
内存zones的实际层次架构取决于硬件,因为并非所有架构都定义了所有的zones,不同平台对DMA的要求也不同。
多处理器机器很多基于 NUMA (Non-Uniform Memory Access system - 非统一内存访问系统 )架构。 在这样的系统中,根据与处理器的“距离”,内存被安排成具有不同访问延迟的 banks 。每个 bank 被称为一个 node ,Linux为每个 node 构造一个独立的内存管理子系统。 Node 有自己的zones集合、free&used页面列表,以及各种统计计数器。
What is NUMA?
NUMA Memory Policy
物理内存易失,将数据放入内存的常见情况是读取文件。读取文件时,数据会放入 页面缓存(page cache) ,可以在再次读取时避免耗时的磁盘访问。同样,写文件时,数据也会被放入 页面缓存 ,并最终进入存储设备。被写入的页被标记为 脏页(dirty page) ,当Linux决定将其重用时,它会将更新的数据同步到设备上的文件。
匿名内存 anonymous memory 或 匿名映射 anonymous mappings 表示没有后置文件系统的内存。这些映射是为程序的stack和heap隐式创建的,或调用mmap(2)显式创建的。通常,匿名映射只定义允许程序访问的虚拟内存区域。读,会创建一个页表条目,该条目引用一个填充有零的特殊物理页。写,则分配一个常规物理页来保存写入数据。该页将被标记为脏页,如果内核决定重用该页,则脏页将被交换出去 swapped out 。
纵贯整个系统生命周期,物理页可用于存储不同类型的数据。它可以是内核内部数据结构、设备驱动DMA缓冲区、读取自文件系统的数据、用户空间进程分配的内存等。
根据内存页使用情况,Linux内存管理会区别处理。可以随时释放的页面称为 可回收(reclaimable) 页面,因为它们把数据缓存到了其他地方(比如,硬盘),或者被swap out到硬盘上。
可回收页最值得注意的是 页面缓存 和 匿名页面 。
在大多数情况下,存放内部内核数据的页,和用作DMA缓冲区的页无法重用,它们将保持现状直到用户释放。这样的被称为 不可回收页(unreclaimable) 。
然而,在特定情况下,即便是内核数据结构占用的页面也会被回收。
例如,文件系统元数据的缓存(in-memory)可以从存储设备中重新读取,因此,当系统存在内存压力时,可以从主内存中丢弃它们。
释放可回收物理内存页并重新调整其用途的过程称为 (surprise!) reclaim 。
Linux支持异步或同步回收页,取决于系统的状态。
当系统负载不高时,大部分内存是空闲的,可以立即从空闲页得到分配。
当系统负载提升后,空闲页减少,当达到某个阈值( low watermark )时,内存分配请求将唤醒 kswapd 守护进程。它将以异步的方式扫描内存页。如果内存页中的数据在其他地方也有,则释放这些内存页;或者退出内存到后置存储设备(关联 脏页 )。
随着内存使用量进一步增加,并达到另一个阈值- min watermark -将触发回收。这种情况下,分配将暂停,直到回收到足够的内存页。
当系统运行时,任务分配并释放内存,内存变得碎片化。
虽然使用虚拟内存可以将分散的物理页表示为虚拟连续范围,但有时需要分配大的连续的物理内存。这种需求可能会提升。例如,当设备驱动需要一个大的DMA缓冲区时,或当THP分配一个大页时。
内存地址压缩(compaction ) 解决了碎片问题。
该机制将占用的页从内存zone的下部移动到上部的空闲页。压缩扫描完成后,zone开始处的空闲页就并在一起了,分配较大的连续物理内存就可行了。
与 reclaim 类似, compaction 可以在 kcompactd守护进程中异步进行,也可以作为内存分配请求的结果同步进行。
在存在负载的机器上,内存可能会耗尽,内核无法回收到足够的内存以继续运行。
为了保障系统的其余部分,引入了 OOM killer 。
OOM killer 选择牺牲一个任务来保障系统的总体健康。选定的任务被killed,以期望在它退出后释放足够的内存以继续正常的操作。
❹ linux 铏氭嫙鍦板潃锛屽埌搴曟庝箞鐞呜В
linux镄勮櫄𨰾熷湴鍧鍒嗕负鐗╃悊鍦板潃鍜岃櫄𨰾熷湴鍧 銆
Linux绯荤粺涓镄勭墿鐞嗗瓨鍌ㄧ┖闂村拰铏氭嫙瀛桦偍绌洪棿镄勫湴鍧锣冨洿鍒嗗埆閮芥槸浠0x00000000鍒0xFFFFFFFF锛屽叡4GB銆
1銆佺墿鐞嗗湴鍧
Linux镄勭墿鐞嗗瓨鍌ㄧ┖闂村竷灞涓庡勭悊鍣ㄧ浉鍏筹纴璇︾粏𨱍呭喌鍙浠ヤ粠澶勭悊鍣ㄧ敤鎴锋坠鍐岀殑瀛桦偍绌洪棿鍒嗗竷琛锛坢emory map锛夌浉鍏崇珷鑺备腑镆ュ埌锛屾垜杩欓噷鍙鍒楀嚭浠ヤ笅鍑犵偣娉ㄦ剰浜嬮”锛
1锛夋渶澶node鍙穘涓嶈兘澶т簬MAX_NUMNODES-1銆
2锛塎AX_NUMNODES琛ㄧず绯荤粺鏀鎸佺殑链澶歯ode鏁般傚湪ARM绯荤粺涓锛孲harp鑺鐗囨渶澶氭敮鎸16涓猲odes锛屽叾浠栬姱鐗囨渶澶氭敮鎸4涓猲odes銆
3锛塶umnodes鏄褰揿墠绯荤粺涓瀹为檯镄勫唴瀛榥ode鏁般
4锛夊湪涓嶆敮鎸丆ONFIG_DISCONTIGMEM阃夐”镄勭郴缁熶腑锛屽彧链変竴涓鍐呭瓨node銆 5锛夋渶澶bank鍙穖涓嶈兘澶т簬NR_BANKS-1銆
6锛垲R_BANKS琛ㄧず绯荤粺涓鏀鎸佺殑链澶у唴瀛榖ank鏁帮纴涓鑸绛変簬澶勭悊鍣ㄧ殑RAM鐗囬夋暟銆侫RM绯荤粺涓锛孲harp鑺鐗囨渶澶氭敮鎸16涓狰anks锛屽叾浠栬姱鐗囨渶澶氭敮鎸8涓狰anks銆
2銆佽櫄𨰾熷瓨鍌ㄧ┖闂村竷灞
鍦ㄦ敮鎸丮MU镄勭郴缁熶腑锛屽綋绯荤粺锅氩畬纭浠跺埯濮嫔寲钖庡氨浣胯兘MMU锷熻兘锛岃繖镙锋暣涓绯荤粺灏辫繍琛屽湪铏氭嫙瀛桦偍绌洪棿涓锛屽疄鐜拌櫄𨰾熷瓨鍌ㄧ┖闂村埌鐗╃悊瀛桦偍绌洪棿鏄犲皠锷熻兘镄勬槸澶勭悊鍣ㄧ殑MMU锛岃岃櫄𨰾熷瓨鍌ㄧ┖闂翠笌5璺瀛桦偍绌洪棿镄勬椠灏勫叧绯诲垯鏄鐢盠inux鍐呮牳𨱒ョ$悊镄勚32浣岖郴缁熶腑鐗╃悊瀛桦偍绌洪棿鍗4GB绌洪棿锛岃櫄𨰾熷瓨鍌ㄧ┖闂村悓镙峰崰4GB绌洪棿锛孡inux鎶婄墿鐞嗙┖闂翠腑瀹为檯瀛桦湪镄勮繙杩滃皬浜4GB镄勫唴瀛樼┖闂存椠灏勫埌鏁翠釜4GB铏氭嫙瀛桦偍绌洪棿涓闄ゆ椠灏処/O绌洪棿涔嫔栫殑鍏ㄩ儴绌洪棿锛屾墍浠ヨ櫄𨰾熷唴瀛樼┖闂磋繙杩滃ぇ浜庣墿鐞嗗唴瀛樼┖闂达纴杩椤氨璇村悓涓鍧楃墿鐞嗗唴瀛桦彲鑳芥椠灏勫埌澶氩勮櫄𨰾熷唴瀛桦湴鍧绌洪棿銆