Chinaunix

标题: linux大海观潮:内存. 交换 [打印本页]

作者: 思一克    时间: 2006-02-21 13:58
标题: linux大海观潮:内存. 交换
linux大海观潮:内存. 交换

思一克


*)物理内存分成页。所以说页,许多时候也就是说物理内存---PM。

*)LINUX将物理内存连续固定影射到虚拟内存(VM)的一块固定区域,如c0000000到c0000000+512M

*)一段虚拟内存,如果小于页大小,同时刻只能对应唯一的物理页。反之不成立。一个页可以同时对应多个虚拟内存VM块。在同一个进程中也是如此。比如在KERNEL中,你bp = vmalloc(1024)得到的VM地址bp,如分得的物理页在zong_normal中, 则还一定有一个VM指针bp1(!=bp)指向同一个物理页。很容易计算出bp1.

*) 在内核KERNEL中,如果有硬盘,交换是很必要的。

*) 什么是交换?交换就是当物理页不太够用时,将某些页的内容写到磁盘上,腾出页来供更需要的人使用。换出到磁盘的内容的所有者在需要时再从磁盘读入页中继续使用。

*) 交换分2种,狭义和广义的。前者是指将页读写到交换文件系统(分区,DOS术语)或交换文件中。后者是一切符合交换定义的读写都包括在内。

*)比如文件系统。我们一般仅仅从磁盘角度来看文件系统的。还可以换一个角度,从内存来看文件系统。事实上后者更合理。因为CPU仅仅认识内存,并不认识磁盘。对CPU来说,文件一定是内存中的文件---inode在内存,dentry在内存,文件内容也在内存。内存比DISK小,所以仅仅有一小部分DISK上的文件成为内存文件。LINUX的icache, dcache, address_space mapping等,就是文件在内存的存储空间。当你读一个文件字节时,不是从DISK直接读,而是从内存文件中读。如果内存没有,那就设法(交换)进来,然后再从内存页中拷贝给用户。写字节也是写入内存文件中,当页紧张时或调用其它函数时候,内存文件就被交换出到DISK上。所以从内存角度看,磁盘文件系统就是自己的交换分区。

*)在linux中什么样的内存能被交换?有的说:用户内存会,内核的内存一定不会被交换。也就是说“The memory in the Kernel/Kernel Module will never be swapped-out”。或者精确点说,内核固定影射的内存不会被交换。上述论断是不正确的。事实上,比如机器物理内存小于896M情况下,被交换的页都是KENREL固定影射的物理页。没有其它的页(这里说的交换不是广义的,而是指与交换文件/分区的交换)。

*)注意交换出去的是页中的内容,换出后物理页还存在,KERNEL中固定影射的VM地址还存在,还要给别人用,此乃交换的本意所在。

*)mudule中也和上面相同。比如shmem.c --- 一个RAM磁盘模块,它所使用的物理内存页(当然都是内核中的内存)就是可交换的。

*)那么,到底什么不能交换?要回答,先看LINUX分配内存页(物理的,虚拟的一样,程序中CPU直接使用的是影射后的虚拟的VM,之间转换简单)的接口。__alloc_pages(), kmalloc()及mem_cache_alloc(),vmalloc(), (通过mmap, address_space操作也可以得到内存)

*)从KERNEL V2.6看,kmalloc()的不能被交换,vmalloc()的也不被交换。只有__alloc_pages()获得的内存才可以(不是一定---分清充分必要)被交换。用户APP运行时,加载copy_mm, copy_process等获得vm_area的都是用__alloc_pages(). mmap()和address_space_ops获得的内存被广义交换。、

*)inode_cachce, dentry_cache等保存在SLAB中的内核分配结构不会被交换。但清理后广义交换(写回磁盘老家)会有的。

*) kmalloc()从SLAB分配的如果某SLAB被释放的成FREE的了,那就可以页回收,并不用交换。

*)vmalloc()仅仅供KERNEL不十分多的地方使用。使用最多的是kmalloc(). vmalloc()以页为单位分配,浪费大。适合一次分配超过kmalloc()能力的大内存块。如果每次用vmalloc分几个字节,内存很快被消耗光。

*)内存光了如何办?oom_killer (Out Of Memory Killer)会被调用,选择大的程序,比如界面KDE的kill掉,以维持机器生命。如果还不行,那就死掉吧。

*)关于free -m显示的问题。
             total       used       free     shared    buffers     cached
Mem:           503        451         52          0         14        293
-/+ buffers/cache:        143        360
Swap:         1027          0       1027
许多时候开机不久Mem:行free列的数值就几乎为0了(52)。道理简单不多废话。流行的说法是这正是LINUX充分利用物理内存的优点。从广义交换,内存文件系统角度看,这并不一定是好事。WHY?cached 和 buffers是内存文件的存在形式。但free很小的时候,并且buffers/cached中脏页比较多时,如果再运行一个大程序比如GCC,如果GCC不在内存,势必要将其它文件换出到DISK(虽然不是全部页都要写盘,比如干净的页),将GCC换入。换出换入是十分影响机器速度的。那GCC为什么不在内存(在buffers, cahced)? 因为GCC上次调用后编译产生的许多中间文件将GCC排挤出去了。所以,Mem:free太小不好,影响机器性能。而
-/+ buers/cache free (360)不代表真实的机器性能,因为是要以换出内存为代价的数值。

*)比如编译KERNEL时,如果有办法让gcc, make, ld等长时间不换出,同时让中间的.c.o等文件短时间换入,那么make速度会提高许多。将gcc等放入不交换的RAMFS有作用。

*)如果机器作为服务器,尤其是托管的仅仅通过SSH连接的机器,不要启动KDE等GUI,可以更快。这也是LINUX比WINDOWS2000好的地方。

*)to be continued.
作者: LuckSnail    时间: 2006-02-21 14:03
一直不明白
-/+ buffers/cache:        143        360
这行该怎么解释才对
作者: lunchan    时间: 2006-02-21 14:11
原帖由 LuckSnail 于 2006-2-21 14:03 发表
一直不明白
-/+ buffers/cache:        143        360
这行该怎么解释才对


是不是為了緩衝而hash了的內存頁面空間
作者: ruf    时间: 2006-02-22 18:19
在2.4内核,vmalloc()内存可能被swap_out,所以如果需要保留一段内存不被swap_out(例如在中断中使用),需要SetPageReserved(vmalloc_to_page((void *)addr));这需要一个一个page的做。

2.6中vmalloc()内存不会swap_out?我还没有研究代码,但是很怀疑。
作者: 思一克    时间: 2006-02-23 08:26
2。6。13 我多次实验过,vmalloc后将MEM占掉,不可以SWAPOUT。




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2