|
楼主 |
发表于 2002-7-22 10:44:05
|
显示全部楼层
Linux 管理员手册(4)--内存管理
本章说明Linux的内存管理特征,即虚拟内存和磁盘缓存。描述系统管理员应该考虑的东西、工作和目的。
什么是虚拟内存?
Linux支持虚拟内存, 就是使用磁盘作为RAM的扩展,使可用内存相应地有效扩大。核心把当前不用的内存块存到硬盘,腾出内存给其他目的。当原来的内容又要使用时,再读回内存。这对用户全透明:运行于Linux的程序只看到大量的可用内存而不甘心哪部分在磁盘上。当然,读写硬盘比真的内存慢(慢千倍),所以程序运行较慢。用做虚拟内存的这部分硬盘叫 对换空间。
Linux可以使用文件系统中的普通文件或单独的分区作为对换空间。对换分区更快,但对换文件更易于改变大小(无须对硬盘重分区)。如果知道要多少对换空间,应该用对换分区;如果不能确认,可以先用对换文件,用一段时间后再根据所需空间建立对换分区。
Linux允许同时使用多个对换分区和/或对换文件。即如果偶尔需要更多的对换空间,可以随时建立一个额外的对换文件。
产生对换空间
对换文件是普通文件,对核心没有什么特别的。唯一不同是它没有孔,用 mkswap 准备。必须在本地盘上,不能在通过NFS mount的文件系统中。
关于孔,是重要的。对换文件保留了磁盘空间,使核心能快速对换出一页,而不必经过如文件的定位磁盘扇区的全部事情。核心只用分配给这个文件的所有扇区。由于文件中的孔意味着没有为文件中这个位置分配磁盘扇区,这对核心使用不利。
产生没有孔的对换文件的一个好办法是通过如下命令:
$ dd if=/dev/zero of=/extra-swap bs=1024 count=1024
1024+0 records in
1024+0 records out
$
/extra-swap 是对换文件名,大小由count=给出. 大小最好是4的倍数,因为核心写出的内存页是4KB。如果不是4的倍数,最后那几KB将不可用。
对换分区也没什么特别。就象产生其他分区一样产生;唯一的不同是它作为原始分区使用,即没有任何文件系统,最好将对换分区标记为类型82(Linux swap),虽然这对核心没有影响,但这使分区列表更清晰。
产生对换文件或对换分区后,需要写个标记起用它,这包括核心要用的一些管理信息。命令是 mkswap , 用法如下:
$ mkswap /extra-swap 1024
Setting up swapspace, size = 1044480 bytes
$
注意对换空间现在还没用,它存在,但核心还没用它提供虚拟内存。
请一定小心使用mkswap , 因为它不检查文件或分区是否被其他东西使用。 你可能用mkswap 很容易地覆盖了重要文件和分区! 幸好,你只需在你安装系统时使用mkswap 。
Linux内存管理限制了每个对换空间约为127MB(由于技术原因,实际限制是127.6875MB)。 可以同时使用最多16个对换空间,总计差不多2GB。
使用对换空间
用swapon 将一个初始化的对换空间可用。此命令告诉核心对换空间可以用了,对换空间的路径作为参数,启动一个临时对换文件可以用如下命令:
$ swapon /extra-swap
$
对换空间如果列入/etc/fstab ,就可自动使用。
/dev/hda8 none swap sw 0 0
/swapfile none swap sw 0 0
启动手稿运行命令swapon -a, 它将启动/etc/fstab 中所列的所有对换空间。因此swapon 命令只有在启动额外的对换空间时才使用。
可以用free 监视对换空间的使用,它将给出所有使用的对换空间。
$ free
total used free shared buffers
Mem: 15152 14896 256 12404 2528
-/+ buffers: 12368 2784
Swap: 32452 6684 25768
$
前一行输出(Mem显示物理内存。 Total列不显示核心使用的物理内存(通常大约1MB)。Used列显示被使用的内存总额(第二行不计缓冲)。 Free列显示全部没使用的内存。Shared列显示多个进程共享的内存总额。Buffers列显示磁盘缓存的当前大小。
后一行(Swap对对换空间,显示的信息类似上面。如果这行为全0,那么没使用对换空间。
通过top ,或使用proc文件系统的/proc/meminfo 文件可以得到相同的信息。得到某个对换空间的使用信息目前还比较困难。
可用swapoff 取消对换空间,一般不必这样,除非是临时对换空间。对换空间中的要用的页被换入(swap->RAM),如果没有足够的物理内存,就被换出(RAM->swap,到其他对换空间)。如果没有足够的虚拟内存放进所有页面,Linux将开始震荡(thrash); 很长时间以后应该能恢复,但此时系统不可用。取消一个对换空间前,应该检查(例如用free )是否有足够的物理内存。
用swapon -a自动使用的所有对换空间可以用swapoff -a取消。它查看文件/etc/fstab 得知要取消什么。任何手工起用的对换空间将依然使用着。
即使有许多空闲的物理内存,有时许多对换空间也被使用着。这种情况是由于在某个时间需要对换,但后来一个占用大量物理内存的大进程终止并释放了内存。直到被换出的数据要被使用之前它们并不自动换入。不必顾虑这种情况,但知道为什么会发生这种情况会更安心。
与其他操作系统共享对换空间
许多操作系统内置虚拟内存。由于他们只需在运行时使用,即,不会同时,那么除了当前运行的,其他所有对换空间都浪费着。如果他们共享同一个对换空间将更有效。这是可能的但需要一些Hacking工作。 Tips-HOWTO包含了一些如何完成这项任务的忠告。
分配对换空间
也许有人告诉你,应该分配2倍于物理内存的对换空间,但这是个虚假的规律。下面说明如何正确:
估计你的全部内存需求。这是你可能需要的最大量,即你要同时运行的所有程序所需的内存要求的总和。你可以同时运行你可能同时运行的所有程序试试。
例如,如果你想运行X,你得分配8MB给他,gcc要求数MB(有些文件偶尔可能需要很大量,数十MB,但一般4MB差不多),等等。核心自己使用1MB,Shell和一些小工具可能需要几百KB(或说,总共1MB)。不必太精确,粗略估计就行,但可以较悲观地考虑。
记得如果将有多人同时使用系统,他们将都消耗内存。如果2个人同时运行相同的程序,总内存消耗一般并非加倍,因为代码页和共享库是单一的。
free 和ps 命令对估计内存需求很有用。
第一步的估计加上一些安全量。因为对程序大小的估计很可能是错误的,因为你可能忘了一些要运行的程序,并确定你有一些额外空间。应该有数MB。(分配太多对换空间比分配太少好,但不必过分,因为不使用的对换空间是浪费;见后文:关于增加对换空间。) Also,since it is nicer to deal with even numbers, you can round the value up to the next full megabyte.
基于以上计算,你知道了你总共需要多少内存。减去你的实际物理内存,就是对换空间。 (有些版本的UNIX中,你还需要分配物理内存的映象空间,所以第二布中计算的你所需的空间就不能减)
如果你计算的对换空间比你的实际物理内存大得多(大于好几倍以上),那么你也许需要更多的物理内存,否则系统性能将太低。
即使计算显示你无须对换空间,最好还是至少有一些。Linux有些侵略性地使用对换空间,这样保持一定的空闲物理内存。即使内存还不为什么程序所需,Linux也会换出一些不用的内存页,这样在需要的时候就可以避免因对换的等待--即对换可以在硬盘空闲的时候提早完成。
对换空间可以分在几个硬盘中,这有时可以提高性能,依赖于这些盘的相对速度和存取模式。你可以尝试几中方案,但要知道正确地尝试是很困难的。不要相信某种方案比其他方案好的断定,因为它不会总是对的。
高速缓存
与存取(真正的)内存相比,从磁盘读是很慢的 另外,在相对短的一端时间里,多次读硬盘相同的部分是很常见的。例如,你可能先读了一封电子邮件,然后回复时又将它读入编辑器,然后复制它到一个文件夹时又用邮件程序读它。或者,考虑命令ls 可能被系统上的很多用户多么频繁地使用。只从磁盘读一次信息,并保持在硬盘中,知道不再需要,除了第一次读,其他都会较快。这就叫磁盘缓存disk buffering,用于此目的的内存叫buffer cache。
不幸的是,由于内存是有限且缺乏的资源,buffer cache一般不会足够大(大到能够装下所有人可能用到的数据)。当cache满时,最长时间不用的数据将被丢弃,内存释放给最新的数据。
磁盘缓冲也用于写操作。要写的数据经常马上又被读(例如一个源代码文件保存到文件中后又被编译器读出),所以将要写的数据放在缓冲里是个好主意。另外,只将数据放如cache而不马上写到磁盘,写操作的程序执行速度更快。写操作然后可以在后台完成,而不降低其他程序的速度。
许多操作系统有buffer caches (即使名称不同),但并非都根据上述原理。有些是透写write-through: 数据马上写到磁盘(当然也同时写到cache) 不马上写的cache叫回写write-back。回写比透写更有效,但也更容易出错:如果系统崩溃,或电源突然掉电,或软盘在cache回写前被取出,那么cache中改变的数据将丢失。这可能意味着文件系统is not in full working order, 可能由于未写数据包含了系统记录信息的重要的变化。
因此,千万不要不经过正常的关闭过程直接关闭电源(见6章), 或没有unmount就取出软盘(如果是mount的),或什么程序还在用着软盘,或软盘灯还在闪。 sync 命令刷新缓冲,即强制将所有未写数据写回磁盘,如果要确保所有数据安全回写,可以用它。传统的UNIX系统中,有个update 程序在后台运行,它每30秒运行一次 sync ,所以通常无须使用sync 。 Linux有一个另外的守侯程序bdflush ,它克服了sync 有时因磁盘I/O负荷太重(因为频繁的操作)而导致有时系统突然呆住的问题。
Linux下,bdflush 由update 启动。一般无须考虑它,但如果bdflush 偶尔因为什么原因死了,核心会给出警告,此时应该手工启动它(/sbin/update )。
cache并不真正缓冲文件,而是块,就是磁盘I/O的最小单元(Linux下,一般是1kB)。这样,所有的目录、超级块、其他文件系统记录数据和无文件系统磁盘都可以被缓冲。
cache的效果决定于其大小。太小的cache几乎无用;它只能cache很少的数据,而可能在被重用前就被清除了。大小有赖于有多少数据被读写,相同的数据的存取频度。唯一的方法是实验。
如果cache是固定大小,那么不应该太大,否则,会由于空闲内存空间太小而使用swap(也很慢)。为了最有效地使用真实内存,Linux自动使用所有空闲内存作为buffer cache,当程序需要更多内存时,自动减少cache。
Linux下,对cache使用无须做任何工作,它完全是自动的。除了要正常关闭系统和取出软盘,无须关心cache。
Linux 管理员手册(5)--引导和关机
本节说明当Linux系统引导和关机时发生了什么,应该任何正确完成. 如果没有遵循正确的过程, 文件可能损坏或丢失.
引导和关机概述
开启计算机并导致其操作系统被加载的过程 叫引导. The name comes from an image of the computer pulling itself up from its bootstraps, but the act itself slightly more realistic.
启动过程中,计算机首先加载了一小段叫 bootstrap loader的程序,它依次加载和启动操作系统, bootstrap loader通常存储在硬盘或软盘的固定的位置. 这2步过程的理由是操作系统大而复杂,而计算机加载的第一段代码很小(几百字节),以免使固件不必要地复杂化.
不同的计算机的bootstrap不同. 对于PC, 计算机(它的BIOS)读软盘或硬盘的第一个扇区(叫 引导扇). bootstrap loader包含在这个扇区中. 它加载位于磁盘(和其他)的其他地方的操作系统.
Linux加载后, 它创始化硬件和设备驱动, 然后运行 init . init 启动其他进程以允许用户登录和做其他事情. 这部分的细节在下面讨论.
为了关闭一个Linux系统, 首先所有进程被告知结束(这使他们关闭所有文件, 完成必要的其他事情, 使之整齐地结束), 然后unmount文件系统和对换区, 最后打印可以关掉电源的信息到控制台. 如果没有遵循正确的过程, 可怕的事情可能发生. 最重要的, 文件系统缓冲cache可能没有回写, 这意味着其中的所有数据将丢失, 磁盘上的文件系统不完整, 并可能不可用.
近观引导过程
可以从软盘或硬盘引导Linux. 安装和开始指南的安装一节 ([Wel]) 告诉你如何安装Linux, 并按你希望的方式引导.
当PC引导后, BIOS做一些测试保证一切正常, 然后开始真正的引导. 它选择一个磁盘(通常是第一个软驱, 如果有软盘的话, 否则就是第一个硬盘, 如果安装了的话; 顺序是可设置的). 然后读第一个扇区, 这叫引导扇; 对于硬盘, 也叫主引导记录, 因为硬盘可以包含多个分区, 每个分区都有自己的引导扇.
引导扇包含一个小程序(小到可以存入一个扇区), 它的责任是从磁盘读入真正的操作系统并启动之. 从软盘启动Linux时, 引导扇包含的代码只读前数百个数据块(当然, 依赖于核心的大小)到预定的内存位置. Linux引导软盘上, 没有文件系统, 核心存在连续的扇区中, 因为这样简化了引导过程. 当然, 使用LILO(LInux LOader)可以从文件系统引导.
从硬盘引导, 主引导记录的代码检查分区表(也在主引导记录扇区中), 确认活动分区(标记为可引导的分区), 从该分区读引导扇区, 然后启动该引导扇区的代码. 该分区的引导扇区的代码做与软盘所做的相同: 从该分区读入核心并启动. 但细节不同, 因为一般只给核心映象做一个单独的分区是没什么用的, 所以分区引导扇中的代码不能只顺序地读磁盘, 它必须找到文件系统把它们放在哪些扇区中. 有几个方法解决这个问题, 但最通常的方法是使用LILO. (关于如何做的细节与这里的讨论无关; 更多的信息请看LILO文档, 它很全面)
用LILO引导时, 它读入并引导缺省核心. 也可以设置LILO, 使之能引导若干个核心之一, 甚至其他操作系统, 也可以在引导时让用户选择引导哪个核心或操作系统. LILO可以设置为如果有人在引导时按住 alt, shift, or ctrl键 (LILO启动时), LILO将不立即引导缺省的而问用户引导哪个. LILO可以设置为带一个timeout选项并询问, 当超时时, 就引导缺省核心.
META: 除了LILO还有其他的引导载入程序, 如loadlin, 它们的信息将在下一版本中给出.
从软盘和硬盘启动各有优势, 但通常从硬盘启动更好, 因为这避免了关于软盘的争论. 而且快. 然而, 安装相同从硬盘启动可能有更多的麻烦, 因此很多人先用软盘引导, 然后当相同工作很好后, 再安装LILO从硬盘引导.
Linux核心被读入内存后, 才真正启动了, 概述如下:
Linux核心是被压缩安装的, 所以它首先得解压自己. 核心映象开头包括一个解压的小程序.
如果你有Linux可识别的super-VGA卡, 且支持一些特殊的文本模式(如100列40行), Linux会问你要用哪个模式. 编译核心时, 可能预定了一个视频模式, 就不会问了. 这也可以用LILO或 rdev 完成.
然后, 核心检查还有什么其他硬件(硬盘, 软盘, 网卡...), 并配置适当的设备驱动; 同时, 输出查找结果的信息. 例如, 我引导时, 得到类似如下信息:
LILO boot:
Loading linux.
Console: colour EGA+ 80x25, 8 virtual consoles
Serial driver version 3.94 with no serial options enabled
tty00 at 0x03f8 (irq = 4) is a 16450
tty01 at 0x02f8 (irq = 3) is a 16450
lp_init: lp1 exists (0), using polling driver
Memory: 7332k/8192k available (300k kernel code, 384k reserved, 176k data)
Floppy drive(s): fd0 is 1.44M, fd1 is 1.2M
Loopback device init
Warning WD8013 board not found at i/o = 280.
Math coprocessor using irq13 error reporting.
Partition check:
hda: hda1 hda2 hda3
VFS: Mounted root (ext filesystem).
Linux version 0.99.pl9-1 (root@haven) 05/01/93 14:12:20
精确的文本在不同系统上不同, 依赖硬件, Linux版本, 及其配置.
然后核心试图mount根文件系统. 位置可在编译时设置, 或在任何时候使用 rdev 或LILO. 文件系统类型自动检测. 如果根文件系统mount 失败, 例如因为你忘了在核心中包含相关的文件系统驱动, 核心将失败, 系统停止(此时没什么可做了).
根文件系统通常被只读mount(这可用与位置相同的方法). 这可使文件系统在mount上时检查; 检查一个可读写的已mount的文件系统可不是个好主意.
然后, 核心在后台启动程序 init (位于/sbin/init ) (它的进程号是1). init 做许多启动工作. 确切的事依赖于设置; 参见章了解更多信息. 它至少要启动一些必要的后台守候程序.
init 然后切换到多用户模式并启动getty ,提供虚拟控制台和串行线. getty 是一个让用户通过虚拟控制台和串行终端登录的程序. init 还可能启动一些其他程序, 基于设置.
至此, 引导完成, 系统启动并正常运行.
关于关机的更多信息
关闭Linux系统时,遵循正确的过程是很重要的。否则,文件系统可能成为废物,文件可能变成杂乱的。这是因为Linux使用磁盘缓存,并不立即将数据写到磁盘,而是间歇地回写。这极大地改善了性能,但同时也意味着如果你只是关闭电源,cache可能保留着大量数据,而磁盘上的数据可能不是一个全部的正在工作的文件系统(因为有些数据已经回写到硬盘,而有些没有)。
另一个不能直接关闭电源的原因是:在多任务系统中,后台可能运行着很多东西,关闭电源可能损失惨重。使用正确的关机顺序,可以保证所有的后台进程得以保存他们的数据。
正常关闭Linux系统的命令是shutdown 。它通常使用2种方法之一。
如果系统只有你一个用户,使用shutdown 的通常方法是退出所有运行程序,从所有虚拟控制台注销,用root登录(如果你已经是root,当然不必再注销、登录,但应该换到根目录,以免由于unmount出现问题),然后运行命令shutdown -h now (虽然单用户时一般不必要,但如果需要一个延时,用一个加号加一个表示分钟的数目代替now)
如果系统是多用户,使用命令shutdown -h +time message, time是到系统停止的分钟数,message是告知所有用户系统关机原因的短信息。
# shutdown -h +10 'We will install a new disk. System should
> be back on-line in three hours.'
#
上面的命令警告所有用户,系统将在10分钟后关闭,他们最好保存信息,否则将丢失。警告将显示在所有登录的终端上,包括所有的xterm 上:
Broadcast message from root (ttyp0) Wed Aug 2 01:03:25 1995...
We will install a new disk. System should
be back on-line in three hours.
The system is going DOWN for system halt in 10 minutes !!
警告在系统关闭前将自动重复数遍,随着时间流逝,间隔越来越短。
当延时之后关闭系统真正开始时,所有文件系统(除了根)被unmount,所有用户进程(如果有人还未注销)被终止,守侯进程被关闭,所有东西都停下来。此后,init 打印出一条信息告知你可以关掉电源了。此时,也只有在此时,你才可以关闭电源。
有时(虽然在任何好的系统上极少),系统可能不能正常关闭。例如,核心紊乱、崩溃等不正常情况,可能无法键入任何命令,因此正常关机可能有些困难,这是只能直接关机。问题可能没那么严重,比如,有人误动了你的键盘,核心和update 程序还在正常运行,等待一些时间可能是个好建议,这能使update 有机会将缓冲cache 中的数据回存硬盘,然后再直接关机。
有人喜欢用sync 三遍来关闭系统,等到磁盘I/O停止,然后在关闭电源。如果没有什么程序运行着,这和用shutdown 等效。然而,它不unmount任何文件系统,可能导致ext2fs的"干净文件系统"标志出问题。这种3遍sync的方法是不推荐使用的。
(In case you're wondering: the reason for three syncs is that in the early days of UNIX, when the commands were typed separately, that usually gave sufficient time for most disk I/O to be finished.)
重启动
重启动就是完全关闭系统,关掉电源,然后再打开。简单方法是用shutdown 重启动系统而不是仅停止系统。这要使用shutdown的 -r选项,例如命令shutdown -r now。
许多Linux系统在按ctrl-alt-del键时运行shutdown -r now。这是可设置的,比如在多用户系统中设置一定的延时也许更好。如果是谁都能接触到的系统,那么最好设置为按ctrl-alt-del什么也不干。
单用户模式
shutdown命令也可用于切换到单用户模式,这种模式谁也不能登录,只有root可以使用控制台。这对系统一般运行时不能做的系统管理任务很有用。单用户模式将在章详细讨论。
紧急引导(软)盘
并非总可以从硬盘引导。例如,LILO设错了,系统可能就无法引导。这时,需要另一个总能引导的方法。对于典型的PC,可能是软驱。
许多Linux distributions允许在安装时产生一张紧急引导盘emergency boot floppy。应该做。然而,有些这样的引导盘只包含核心,and assume you will be using the programs on the distribution's installation disks to fix whatever problem you have。有时这些程序是不够的:例如你可能需要回存你的备份,而备份/回存软件在Linux安装盘里没有。
因此,可能需要自己产生root盘。 Graham Chapman写的Bootdisk HOWTO([Cha]) 包含关于此的指导。当然,你必须记得使你的紧急引导盘和root盘最新。
root盘被mount上时,不能用软驱干其他任何事,因此如果你只有一个软驱可能不太方便。然而,如果你有足够的内存,可以设置引导盘将root盘加载到RAM盘上(为此,引导盘的核心需要特殊设置)。一旦root盘被加载到RAM盘中,软驱就可以用于mount其他盘了。 |
|