HTTP缓存协议原理解析及应用指南

http协议里控制浏览器缓存的头有三个Cache-Control,Expires,Last-Modified
对于静态页面还有Etag。
一、先来看第一种情况:apache 静态页面
apache发送给客户端的静态页面一般包含Last-Modified和Etag,这两个标签的值来自静态文件的修改时间和inode,
下面是截取得apache返回客户端的头
———
Last-Modified: Fri, 26 Jan 2007 01:53:34 GMT
ETag: "3f9f640-318-cb9f8380"
———
搜索引擎之所以喜欢静态文件是因为有这两个标识,可以判断文件是否更新过

二、PHP等动态页面
由于php是动态生成的,它的内容是不能根据php程序的时间来确定最后修改日期,所以默认php返回客户端的时候补包含任何缓存控制,要想利用好缓存就必须了解缓存机制,和理减少b,s的交互,缩减带宽流量,减轻服务器负担…好处多多

三、缓存控制的具体含义
先解释一下本人经过测试理解的这几个标签的含义
Cache-Control:指定请求和响应遵循的缓存机制。在请求消息或响应消息中设置Cache-Control并不会修改另一个消息处理过程中的缓存处理过程。请求时的缓存指令包括no-cache、no-store、max-age、max-stale、min-fresh、only-if-cached,响应消息中的指令包括public、private、no-cache、no-store、no-transform、must-revalidate、proxy-revalidate、max-age。各个消息中的指令含义如下:
Public指示响应可被任何缓存区缓存。
Private指示对于单个用户的整个或部分响应消息,不能被共享缓存处理。这允许服务器仅仅描述当用户的部分响应消息,此响应消息对于其他用户的请求无效。
no-cache指示请求或响应消息不能缓存
no-store用于防止重要的信息被无意的发布。在请求消息中发送将使得请求和响应消息都不使用缓存。
max-age指示客户机可以接收生存期不大于指定时间(以秒为单位)的响应。
min-fresh指示客户机可以接收响应时间小于当前时间加上指定时间的响应。
max-stale指示客户机可以接收超出超时期间的响应消息。如果指定max-stale消息的值,那么客户机可以接收超出超时期指定值之内的响应消息。
php用法:
在输出之前用header(),(如果使用ob_start()可以将header放在程序任意地方)
header(‘Cache-Control: max-age=8’);
max-age=8表示最大生存期8秒,超过8秒浏览器必须去服务器重新读取,这个时间是以用户的读取页面开始计时的,而Expires是绝对时间。
Expires:缓存过期的绝对时间,如果过了它指定的那个时间点,浏览器就不认缓存了,要去服务器重新请求一份最新的。

Last-Modified:文档的最后修改时间,它的妙用就是:1 如果是静态文件,客户端会发上来它缓存里的时间,apache会来比对,如果发现没有修改就直接返回一个头,状态码是304,字节数非常少,(高级版本还会增加比较Etag来确定文件是否变化)
2 php动态文件: 客户端发上比对时间,php会判断是否修改,如果修改时间相同,就只会返回1024字节,至于为什么返回1024不得而知,如果你的php生成的文件非常大,它也只返回1024,所以比较省带宽,客户端会根据服务器端发过来的修改时间自动从缓存文件里显示。

注:如果没有Last-Modified头,Cache-Control和Expires也是可以起作用的,但每次请求要返回真实的文件字节数,而不是1024

四、HOW ?
静态页面不用去管它了,如果想更好的控制静态页面的缓存,apache有几个模块可以很好的控制,这里不讨论
php页面:
这里分两种:1 不经常改动的页面,类似新闻发布,这类页面的特点:第一次发布之后会有几次改动,随着时间推移基本不会再修改。控制策略应该是:1第一次发布之发送Last-Modified,max-age设定1天,修改过之后更新Last-Modified,max-age时间随着修改次数正常。这样似乎比较繁琐,还要记录修改次数,也可以预计一下下次可能的修改时间用Expires指定到大概时间过期
php代码:
//header(‘Cache-Control: max-age=86400’);//缓存一天
header(‘Expires: Mon, 29 Jan 2007 08:56:01 GMT’);//指定过期时间
header(‘Last-Modified: ‘.gmdate(‘D, d M Y 01:01:01′,$time).’ GMT’);//格林尼治时间,$time是文件添加时候的时间戳
2 经常改动的页面  类似bbs,论坛程序,这种页面更新速度比较快,缓存的主要作用是防止用户频繁刷新列表,导致服务器数据库负担,既要保证更新的及时性,也要保证缓存能被利用
这里一般用Cache-Control来控制,根据论坛的发帖的频率灵活控制max-age。
header(‘Cache-Control: max-age=60’);//缓存一分钟
header(‘Last-Modified: ‘.gmdate(‘D, d M Y 01:01:01′,$time).’ GMT’);//格林尼治时间,$time是帖子的最后更新时间戳

五 额外
1 刷新,转到,强制刷新的区别
浏览器上有刷新和转到按键,有的浏览器支持用ctrl+F5强制刷新页面,它们的区别是什么?
转到:用户点击链接就是转到,它完全使用缓存机制,如果有Last-Modified那么不会和服务器通讯,用抓包工具可以查看到发送字节是0byte,如果缓存过期,那么它会执行F5刷新的动作。
刷新(F5):这种刷新也是根据缓存是否有Last-Modified来决定,如果有会转入304或1024(php),如果没有最后更新时间那么去服务器读取,返回真实文档大小
强制刷新:完全抛弃缓存机制,去服务器读取最新文档,向服务器发送的header如下
Cache-Control: no-cache

2 调试工具
查看浏览器和服务器交互比较好的工具是httpwatch pro,现在的版本4.1,支持ie7
还有别的代理抓包工具可以分析,http debugging。没用过,还有tcp抓包工具,2000自带的network monitor不过不是专门针对http的比较难用

六 声明
本文作者保留所有权力,允许被自由查看和转载,但必须指明作者(Ash)和源网址(www.cosrc.com);不允许商用

 

相关资料:
http://www.zgkw.cn/FORUMS/forums/59660/ShowThread.aspx
http://www.javaeye.com/topic/119336
http://www.happyshow.org/article/209.html

开心果

爹跟儿子说:我要给你找个媳妇。
儿子说,可我愿意自己找! 
爹说,但这个女孩子是比尔盖茨女儿!
儿子说,要是这样,可以。
然后他爹找到比尔盖茨,说,我给你女儿找了一个老公。
比尔盖茨说,不行,我女儿还小!
爹说,可是这个小伙子是世界银行副总裁! 
比尔盖茨说,啊,这样,行!
最后,爹找到了世界银行总裁,说,我给你推荐一个副总裁!
总裁说,可是我有太多副总裁了,多余了!
爹说,可是这个小伙子是比尔盖茨的女婿! 
总裁说,这样,行!
               —-生意是这样做成的

Apache 2.0中prefork.c模块和worker.c模块的比较

Apache 2.XX中prefork.c模块和worker.c模块的比较

空闲子进程:是指没有正在处理请求的子进程。

1、prefork.c模块(一个非线程型的、预派生的MPM)
prefork MPM 使用多个子进程,每个子进程只有一个线程。每个进程在某个确定的时间只能维持一个连接。在大多数平台上,Prefork MPM在效率上要比Worker MPM要高,但是内存使用大得多。prefork的无线程设计在某些情况下将比worker更有优势:它可以使用那些没有处理好线程安全的第三方模块,并且对于那些线程调试困难的平台而言,它也更容易调试一些。

<IfModule prefork.c>
ServerLimit 20000
StartServers 5
MinSpareServers 5
MaxSpareServers 10
MaxClients 1000
MaxRequestsPerChild 0
</IfModule>

ServerLimit 2000
//默认的MaxClient最大是256个线程,如果想设置更大的值,就的加上ServerLimit这个参数。20000是ServerLimit这个参数的最大值。如果需要更大,则必须编译apache,此前都是不需要重新编译Apache。
生效前提:必须放在其他指令的前面

StartServers 5
//指定服务器启动时建立的子进程数量,prefork默认为5。

MinSpareServers 5
//指定空闲子进程的最小数量,默认为5。如果当前空闲子进程数少于MinSpareServers ,那么Apache将以最大每秒一个的速度产生新的子进程。此参数不要设的太大。

MaxSpareServers 10
//设置空闲子进程的最大数量,默认为10。如果当前有超过MaxSpareServers数量的空闲子进程,那么父进程将杀死多余的子进程。此参数不要设的太大。如果你将该指令的值设置为比MinSpareServers小,Apache将会自动将其修改成"MinSpareServers+1"。

MaxClients 256
//限定同一时间客户端最大接入请求的数量(单个进程并发线程数),默认为256。任何超过MaxClients限制的请求都将进入等候队列,一旦一个链接被释放,队列中的请求将得到服务。要增大这个值,你必须同时增大ServerLimit 。

MaxRequestsPerChild 10000
//每个子进程在其生存期内允许伺服的最大请求数量,默认为10000.到达MaxRequestsPerChild的限制后,子进程将会结束。如果MaxRequestsPerChild为"0",子进程将永远不会结束。

将MaxRequestsPerChild设置成非零值有两个好处:
1.可以防止(偶然的)内存泄漏无限进行,从而耗尽内存。
2.给进程一个有限寿命,从而有助于当服务器负载减轻的时候减少活动进程的数量。

工作方式:
一个单独的控制进程(父进程)负责产生子进程,这些子进程用于监听请求并作出应答。Apache总是试图保持一些备用的(spare)或者是空闲的子进程用于迎接即将到来的请求。这样客户端就不需要在得到服务前等候子进程的产生。在Unix系统中,父进程通常以root身份运行以便邦定80端口,而Apache产生的子进程通常以一个低特权的用户运行。User和Group指令用于设置子进程的低特权用户。运行子进程的用户必须要对它所服务的内容有读取的权限,但是对服务内容之外的其他资源必须拥有尽可能少的权限。

2、worker.c模块(支持混合的多线程多进程的多路处理模块)
worker MPM 使用多个子进程,每个子进程有多个线程。每个线程在某个确定的时间只能维持一个连接。通常来说,在一个高流量的HTTP服务器上,Worker MPM是个比较好的选择,因为Worker MPM的内存使用比Prefork MPM要低得多。但worker MPM也由不完善的地方,如果一个线程崩溃,整个进程就会连同其所有线程一起"死掉".由于线程共享内存空间,所以一个程序在运行时必须被系统识别为"每个线程都是安全的"。

<IfModule worker.c>
ServerLimit 50
ThreadLimit 200
StartServers 5
MaxClients 5000
MinSpareThreads 25
MaxSpareThreads 500
ThreadsPerChild 100
MaxRequestsPerChild 0
</IfModule>

ServerLimit 16
//服务器允许配置的进程数上限。这个指令和ThreadLimit结合使用设置了MaxClients最大允许配置的数值。任何在重启期间对这个指令的改变都将被忽略,但对MaxClients的修改却会生效。

ThreadLimit 64
//每个子进程可配置的线程数上限。这个指令设置了每个子进程可配置的线程数ThreadsPerChild上限。任何在重启期间对这个指令的改变都将被忽略,但对ThreadsPerChild的修改却会生效。默认值是"64".

StartServers 3
//服务器启动时建立的子进程数,默认值是"3"。

MinSpareThreads 75
//最小空闲线程数,默认值是"75"。这个MPM将基于整个服务器监视空闲线程数。如果服务器中总的空闲线程数太少,子进程将产生新的空闲线程。

MaxSpareThreads 250
//设置最大空闲线程数。默认值是"250"。这个MPM将基于整个服务器监视空闲线程数。如果服务器中总的空闲线程数太多,子进程将杀死多余的空闲线程。MaxSpareThreads的取值范围是有限制的。Apache将按照如下限制自动修正你设置的值:worker要求其大于等于MinSpareThreads加上ThreadsPerChild的和

MaxClients 400
//允许同时伺服的最大接入请求数量(最大线程数量)。任何超过MaxClients限制的请求都将进入等候队列。默认值是"400",16(ServerLimit)乘以25(ThreadsPerChild)的结果。因此要增加MaxClients的时候,你必须同时增加ServerLimit的值。

ThreadsPerChild 25
//每个子进程建立的常驻的执行线程数。默认值是25。子进程在启动时建立这些线程后就不再建立新的线程了。

MaxRequestsPerChild 0
//设置每个子进程在其生存期内允许伺服的最大请求数量。到达MaxRequestsPerChild的限制后,子进程将会结束。如果MaxRequestsPerChild为"0",子进程将永远不会结束。

将MaxRequestsPerChild设置成非零值有两个好处:
1.可以防止(偶然的)内存泄漏无限进行,从而耗尽内存。
2.给进程一个有限寿命,从而有助于当服务器负载减轻的时候减少活动进程的数量。
注意
对于KeepAlive链接,只有第一个请求会被计数。事实上,它改变了每个子进程限制最大链接数量的行为。

工作方式:
每个进程可以拥有的线程数量是固定的。服务器会根据负载情况增加或减少进程数量。一个单独的控制进程(父进程)负责子进程的建立。每个子进程可以建立ThreadsPerChild数量的服务线程和一个监听线程,该监听线程监听接入请求并将其传递给服务线程处理和应答。Apache总是试图维持一个备用(spare)或是空闲的服务线程池。这样,客户端无须等待新线程或新进程的建立即可得到处理。在Unix中,为了能够绑定80端口,父进程一般都是以root身份启动,随后,Apache以较低权限的用户建立子进程和线程。User和Group指令用于设置Apache子进程的权限。虽然子进程必须对其提供的内容拥有读权限,但应该尽可能给予它较少的特权。另外,除非使用了suexec ,否则,这些指令设置的权限将被CGI脚本所继承。

公式:
ThreadLimit >= ThreadsPerChild
MaxClients <= ServerLimit * ThreadsPerChild 必须是ThreadsPerChild的倍数
MaxSpareThreads >= MinSpareThreads+ThreadsPerChild

硬限制:

ServerLimi和ThreadLimit这两个指令决定了活动子进程数量和每个子进程中线程数量的硬限制。要想改变这个硬限制必须完全停止服务器然后再启动服务器(直接重启是不行的)。

Apache在编译ServerLimit时内部有一个硬性的限制,你不能超越这个限制。
prefork MPM最大为"ServerLimit 200000"
其它MPM(包括work MPM)最大为"ServerLimit 20000

Apache在编译ThreadLimit时内部有一个硬性的限制,你不能超越这个限制。
mpm_winnt是"ThreadLimit 15000"
其它MPM(包括work prefork)为"ThreadLimit 20000

注意
使用ServerLimit和ThreadLimit时要特别当心。如果将ServerLimit和ThreadLimit设置成一个高出实际需要许多的值,将会有过多的共享内存被分配。当设置成超过系统的处理能力,Apache可能无法启动,或者系统将变得不稳定。

上帝没给它鱼鳔

   上帝造了一群鱼,种类多样,大小各异。它们的身体被做成流线型,而且十分光滑,还拥有短而有力的鳍,这样就能在大海中自由自在地游动。

这些鱼被放入大海后,上帝忽然想起一个问题,鱼的身体比重大于水,它们一旦停止游动,就会下沉,很可能被水压死。

上帝赶紧找到这些鱼,又给了它们一个法宝——鱼鳔。有了鱼鳔,鱼就轻松多了,它们不但随意沉浮,还可以停在某地休息。鱼鳔对于鱼来讲,实在太有用了。

但是,上帝费了好大劲也没有找到鲨鱼。鲨鱼是个调皮的家伙,它一入海,便撒着欢儿地跑远了。上帝想,既然找不到鲨鱼,那就算了,它会由于缺少鳔而沦为海洋中的弱者,最后被淘汰。

亿万年后,上帝忽然想看看当年放到海中的鱼现在到底如何了。上帝把海里的鱼都找了来,经过亿万年的演变,所有的鱼都变了模样。

面对千姿百态、大大小小的鱼,上帝问:“谁是当初的鲨鱼?”一群威猛强壮的鱼游上前来,它们就是当初的鲨鱼,现在的“海霸王”。上帝十分惊讶,心想当初只有鲨鱼没有鱼鳔,它要比别的鱼多承受多少压力和风险啊,可现在看来,鲨鱼无疑是鱼类中的佼佼者。

鲨鱼说:“我们没有鱼鳔,无时无刻不承受着压力,所以我们就一刻不停地游动,否则就会被水压死。亿万年来,我们从未停止过游动和抗争,这成了我们的生存方式。”

上帝恍然大悟。

   

  我们如这些鱼儿.所以只有生于忧患,不能沉缅安逸,才会变的更加有本事.天大的本事都是被逼而出,这种可怕优势,而这一切源于天生缺少的一件重要的法宝。

佛曰

佛曰:人生有八苦:生,老,病,死,爱别离,怨长久,求不得,放不下。

佛曰:命由己造,相由心生,世间万物皆是化相,心不动,万物皆不动,心不变,万物皆不变。

佛曰:笑着面对,不去埋怨。悠然,随心,随性,随缘。注定让一生改变的,只在百年后,那一朵花开的时间。

佛曰:刹那便是永恒。

佛曰:爱别离,怨憎会,撒手西归,全无是类。不过是满眼空花,一片虚幻。

佛曰:由爱故生忧,由爱故生怖,若离于爱者,无忧亦无怖

佛曰:以物物物,则物可物;以物物非物,则物非物。物不得名之功,名不得物之实,名物不实,是以物无物也。

佛曰:一念愚即般若绝,一念智即般若生。

佛曰。坐亦禅,行亦禅,一花一世界,一叶一如来,春来花自青,秋至叶飘零,无穷般若心自在,语默动静体自然。

佛曰:吾法念无念念。行无行行。言无言言。修无修修。会者近尔。迷者远乎。言语道断。非物所拘。差之毫厘。失之须臾。

佛曰:如人锻铁。去滓成器。器即精好。学道之人。去心垢染。行即清净矣。

佛曰。净心守志。可会至道。譬如磨镜。垢去明存。断欲无求。当得宿命。

佛曰:缘来则去,缘聚则散,缘起则生,缘落则灭。

佛曰:笑着面对,不去埋怨。悠然,随心,随性,随缘。注定让一生改变的,只在百年后,那一朵花开的时间。

佛曰:种如是因,收如是果,一切唯心造。

问曰:“为何人有善恶之分?”
佛曰:“人无善恶,善恶存乎尔心”
问曰:“如何能静?如何能常?”
佛曰:“寻找自我。”
问曰:“世间为何多苦恼?”
佛曰:“只因不识自我。”
问曰:“人为何而活?”
佛曰:“寻根。”
问曰:“何谓之根?”
佛曰:“不可说。”
佛曰:不可说,不可说,一说即是错

“人之一辈子,有生必有死。为生而筹计者,是为生计。若按年龄区分,则一岁至十岁,为生计;二十至三十,为家计;三十至四十,为子孙计,五十至六十,为老计;六十至七十以上,则为死计。从二十至六十这四十年间,营营扰扰,或为功名,或为事业。外则苦其身以事劳攘,内则苦其心以密思虑,既要想目下的周身之防,又要想将来的善后之策,总而言之是劳碌一生。”

夫妻定律

炒菜定律:经常炒菜的肯定是妻子,炒菜好吃的肯定是丈夫。

忠诚定律:妻子越是爱丈夫,丈夫对妻子越是忠;丈夫越是爱妻子,妻子越是对丈夫不忠诚。

花钱定律:妻子把钱花在打扮(美容、穿戴)上,丈夫把钱花在过(烟、酒、牌……)瘾上。

买菜定律:一到菜市场就不知买什么菜好的多是妻子,一到菜市场见啥菜买啥菜的多是丈夫。

成熟定律:越是被妻子深爱着的丈夫越是成熟,越是被丈夫娇宠着的妻子就越是不成熟。

说话定律:夫妻之间谁说得话越多,谁的话就越没分量。

伤害定律:夫妻之间,一方对另一方付出得越多,分手时所得到的伤害越大。

抱怨定律:经常抱怨的总是妻子,经常被抱怨的总是丈夫。

干活定律:在丈夫的眼里,家里总是没有什么活;在妻子的眼里,家里总是有干不完的活。

做事定律:做事见好就收的总是丈夫,做事想好上加好的总是妻子。

着装定律:男人只有合身的服装而缺少流行的服装;女人只有流行的服装而缺少合身的服装。

洗碗定律:妻子洗碗易净,丈夫洗碗易碎。

唠嗑定律:越唠越有精神的多是妻子,越唠话越少的多是丈夫。

回家定律:妻子一出门就想回家,丈夫一出门就不爱回家;妻子一旦不愿回家,丈夫就得匆匆回家;丈夫一旦不愿回家,妻子迟早也得离家。

吵架定律:夫妻越是毫无原因的吵架越是吵得越凶。

讥笑定律:在懂得爱情的夫妻那里,相互间的讥笑会演化成一种幽默,在不懂得爱情的夫妻那里,相互间的讥笑会演化成一场战争。

距离定律:有时候夫妻之间的地理距离越远,情感距离越近。

危机定律:当家庭经济出现危机之时,丈夫的想法总是希望妻子帮自己一把,而妻子的想法是能否换一个丈夫。

脾气定律:夫妻之间,挣钱多少决定脾气大小,不挣钱的人没脾气。

平等定律:夫妻双方都认为自己是家长,可重大的事情又一个人说了不算。

劝说定律:夫妻之间一旦发生矛盾,出面劝说的人越多,矛盾越是不容易解决。

编后:婚姻是种艺术,如果两个人都能找到适合自己的模式,那么就一起厮守吧。

2006年年度总结报告—-这年头

2006年年度总结报告

这年头,大棚把季节搞乱,小姐把辈份搞乱,关系把程序搞乱,级别把能力搞乱,公安把秩序搞乱,金钱把官场搞乱,手机把家庭搞乱!

这年头,女人漂亮的不下厨房,下厨房的不温柔,温柔的没主见,有主见的没女人味,有女人味的乱花钱,不乱花钱的不时尚,时尚的不放心,放心的没法看!

这年头,老婆像小灵通经济实惠但限本地使用,二奶像中国电信安全固定但带不出门,小蜜像中国移动使用方便但话费太贵。情人像中国联通优雅新潮但常不在服务区!

这年头,一哥们说北京地铁拥挤不堪他怀孕的老婆竟被挤流产了;昨天他问上海的地铁是不是好些,上海的哥们说更糟:上个月他老婆乘地铁竟然被挤怀孕了!

这年头,教授摇唇鼓舌,四处赚钱,越来越像商人;商人现身讲坛,著书立说,越来越像教授。医生见死不救,草菅人命,越来越像杀手;杀手出手麻利,不留后患,越来越像医生。明星卖弄风骚,给钱就上,越来越像妓女;妓女楚楚动人,明码标价,越来越像明星。警察横行霸道,欺软怕硬,越来越像地痞;地痞各霸一方,敢做敢当,越来越像警察。

这年头,军委领导说解放军的工资如果翻四倍可以打美国,翻三倍可以打日本,翻两倍可以打台湾,翻一倍可以回家打老婆,目前的工资回家只能被老婆打!!

Linux 进程的内存使用解析

Linux下如果知道一个进程究竟占用了多少内存?这是个经常被问道和被答错的问题。进程的内存分配是个比较复杂的话题,这里通过一个例子进行说明。

有这么一个简单程序:

[root@pczou pczou]# cat ./prog.c
#include <stdio.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

#define ONEM (1024*1024)

int func()
{
char s[16*ONEM];
char* p;
p = malloc(32*ONEM);
pause();
return 0;
}

int main()
{
printf("pid: %d\n", getpid());
func();
return 0;
}

其中func()这个函数分配了32MB的内存,以及16MB的堆栈。

运行一下,prog会停在pause()的位置,看看ps怎么说:

USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 4238 0.0 0.0 52396 352 pts/0 S 21:29 0:00 ./prog

VSZ指的是进程内存空间的大小,这里是52396KB;
RSS指的是驻留物理内存中的内存大小,这里是352KB。

一般系统管理员知道VSZ并不代表进程真正用到的内存,因为有些空间会仅在页表中挂个名,也就是说只是虚拟存在着,只有真正用到的时候内核才会把虚拟页面和真正的物理页面映射起来。比如,prog.c中用malloc()分配的32MB内存,由于程序中并没有用到这些内存,所以不应算到进程的帐上。

进程的内存使用情况比较复杂,这是因为:

        

  • 进程申请的内存不一定真正会被用到
  •     

  • 真正用到的内存也不一定是只有该进程自己在用 (比如动态共享库)
        

所以酒足饭饱结帐的时候,酒吧打出的帐单中不应该有没有上的菜,也不应该一个菜两份钱。而ps给出的就是这样的“糊涂”帐单,不足为凭。

算清楚帐的唯一办法是把每个菜都仔细过一遍,看看有没有上,有没有重复。下面的帐单要清楚多了:

Virtual memory : 52396 KB
Effective VM : 52120 KB
Mapped : 352 KB
Effective mapped: 76.6 KB
Sole use : 72 KB

Per file memory use
ld-2.3.4.so : VM 94208 B, M 90112 B, S 8192 B
prog : VM 8192 B, M 8192 B, S 8192 B
libc-2.3.4.so : VM 1180 KB, M 221184 B, S 16384 B

可以看出,虽然虚拟地址空间是52396KB,实际映射(a.k.a. 分配)的空间是352KB,这和ps给出的结果一致。再看"Effective Mapped"这个值,仅为76.6 KB。这个值的计算方法是:

有效的实际使用内存 = 该进程独占的内存 + 共享的内存A /共享A的进程数目 + 共享的内存B /共享B的进程数目 + …

虽然并不十分准确,但"Effective Mapped"已经足以说明进程所占用内存的实际大小了。

OK,最后用这个方法给所有进程都“结下帐”:

从上面的统计结果可以看出,

        

  • 虽然firefox的占用虚拟空间是最大的,但其实际占用的内存却比X Server要少。
  •     

  • firefox的实际占用的内存和其RSS (a.k.a. mapped)差别不大,只有少了约700;而kontact的实际占用的内存比起RSS足足少了约1.2MB。由此可以看出我用的窗口管理器是KDE而非Gnome,why? 因为Qt之类的共享库被很多KDE进程分担了。

linux下常见的性能分析工具介绍

工具介绍-vmstat
vmstat是个很全面的性能分析工具,能够观察到系统的进程状态、内存使用、虚拟内存使用、磁盘的IO、中断、上下问转换、CPU使用等。系统性能分析工具中,我使用最多的是这个,除了 sysstat 工具包外,这个工具能查看的系统资源最多。

对于 Linux 的性能分析,100%理解 vmstat 输出内容的含义,那您对系统性能分析的能力就算是基本掌控了。

我这里主要说明一下这个命令显示出的部分数据代表的含义,和他反映出系统相关资源的状况。输出内容共有 6 类,分别说明如下。

Procs
r:
运行的和等待(CPU时间片)运行的进程数,这个值也能够判断是否需要增加CPU(长期大于1)
b:
处于不可中断状态的进程数,常见的情况是由IO引起的

Memory
swpd: 转换到交换内存上的内存(默认以KB为单位)
假如 swpd 的值不为0,或还比较大,比如超过100M了,但是 si, so 的值长期为 0,这种情况我们能够不用担心,不会影响系统性能。
free: 空闲的物理内存
buff: 作为buffer cache的内存,对块设备的读写进行缓冲
cache: 作为page cache的内存, 文档系统的cache
假如 cache 的值大的时候,说明cache住的文档数多,假如频繁访问到的文档都能被cache住,那么磁盘的读IO bi 会很小。

Swap
si: 交换内存使用,由磁盘调入内存
so: 交换内存使用,由内存调入磁盘
内存够用的时候,这2个值都是0,假如这2个值长期大于0时,系统性能会受到影响。磁盘IO和CPU资源都会被消耗。
我发现有些朋友看到空闲内存(free)很少或接近于0时,就认为内存不够用了,实际上不能光看这一点的,还要结合si,so,假如free很少,但是si,so也很少(大多时候是0),那么不用担心,系统性能这时不会受到影响的。

Io
bi: 从块设备读入的数据总量(读磁盘) (KB/s),
bo: 写入到块设备的数据总理(写磁盘) (KB/s)
随机磁盘读写的时候,这2个 值越大(如超出1M),能看到CPU在IO等待的值也会越大

System
in: 每秒产生的中断次数
cs: 每秒产生的上下文转换次数
上面这2个值越大,会看到由内核消耗的CPU时间会越多

Cpu
us: 用户进程消耗的CPU时间百分比
us 的值比较高时,说明用户进程消耗的CPU时间多,但是假如长期超过50% 的使用,那么我们就该考虑优化程式算法或进行加速了(比如 PHP/Perl)
sy: 内核进程消耗的CPU时间百分比
sy 的值高时,说明系统内核消耗的CPU资源多,这并不是良性的表现,我们应该检查原因。
wa: IO等待消耗的CPU时间百分比
wa 的值高时,说明IO等待比较严重,这可能是由于磁盘大量作随机访问造成,也有可能是磁盘的带宽出现瓶颈(块操作)。
id: CPU处在空闲状态时间百分比

情景分析
这个vmstat的输出那些信息值得关注?
Procs r: 运行的进程比较多,系统很繁忙
Io bo: 磁盘写的数据量稍大,假如是大文档的写,10M以内基本不用担心,假如是小文档写2M以内基本正常
Cpu us: 持续大于50,服务高峰期能够接受
Cpu wa: 稍微有些高
Cpu id:持续小于50,服务高峰期能够接受

///////////////////////
工具介绍-top

这个命令能够查看系统中运行的进程的状况,CPU使用状况,系统负载,内存使用等。他是检查系统进程运行状况最方便的工具了,他默认显示部分活动的进程,并且按照进程使用CPU的多少排序。他能够显示全部CPU的使用状况,也能够显示每个进程都运行在那个CPU上面。

我习惯使用这个命令查看那些进程或那类进程占用CPU和内存资源最多,以此迅速定位存在性能问题的进程,连同运行异常的进程。

用 top 看到的内存的说明(Mem的第2行)
actv
active 活跃的内存页,正在映射给进程使用
in_d
inactive_dirty 非活跃的内存页,并且内存数据被修改,需要写回磁盘
in_c
inactive_clean 非活跃的内存页,干净的数据,能够被重新分配使用
用 top 看到的进程所处的几种状态(STAT列)。
D 不可中断休眠,通常是 IO 操作所处的状态
R 正在执行的或处在等待执行的进程队列中
S 休眠中
T 暂停刮起的(比如Ctrl+Z),也可能是被 strace 命令调用中的状态
Z 僵尸进程,进程执行完成,但由于其父进程没有销毁该进程,而被init进程接管进行销毁。
W 没有使用物理内存,所占用的物理内存被转换到交换内存
高优先级的进程
N 低优先级

有时候一个进程会有多个状态的标志,比如SWN,SW

情景分析
前面两次top的输出那些信息值得关注?
图1)
Load average: 系统负载有降低的趋势,但仍然较高
Running: 有3个进程正在运行,正常,因为系统有4颗CPU
Cpu user: 接近200%了,有些大,服务高峰时能够接受
Cpu idle: 小于200%了,需要注意
图2)
Cpu iowait:接近200%了,很大

工具介绍-free
free命令显示系统内存的使用状况(物理内存和交换内存)
通过这个命令我们能够看到系统进程实际使用的物理内存,buffer和cache使用的物理内存

free命令输出的第二行(Mem)
这行分别显示了物理内存的总量(total)、已使用的(used)、空闲的(free)、共享的(shared)、buffer、cache的内存。

free命令输出的第三行(-/+ buffers/cache)
这行最容易让人迷惑。
他显示的第一个值(used这一列)是这样得来的:
Mem行used列 – Mem行buffers列 – Mem行cached列

他显示的第二个值(free这一列)是这样得来的:
Mem行free列 + Mem行buffers列 + Mem行cached列

free命令输出的第四行(Swap)
这行显示交换内存的总量、已使用量、空闲量

通常 buffer 和 cache 能够使用的内存空间越大,系统 IO 和 文档系统访问的性能越好。

工具介绍-uptime
最简便的查看系统负载的工具,系统负载越小,系统运行状况越好,对于系统负载处在什么范围内比较合适,我想是没有定论的,我介绍一下我的习惯。

我一般以15分钟负载的值来评估系统的健康度,以10为这个值的临界点,假如系统负载持续高于10,通常是存在某个资源长期紧张的原因,我们需要重视,并且得开始着手解决这个问题了。

假如偶尔高于10,应该开始留意他出现的频度,这往往是前面一种状况的先兆。