+ -
当前位置:首页 → 问答吧 → 非计算内存和计算内存的概念

非计算内存和计算内存的概念

时间:2008-06-19

来源:互联网

看到有XD发帖说这个问题,我也想详细给大家一个说明,请各位老手新手指教。

通俗的说法:
凡是硬盘上有对应的数据,占用的内存,就是非计算内存,非计算内存需要被别的进程用到时,其中的数据无需page out,因为再次需要读取的时候从硬盘文件中拿出来即可。

凡是硬盘上没有数据对应的内存占用叫做计算内存,例如用C写个程序,分配一块1MB的内存,这部分内存不管其中数据是否有意义,硬盘上没有文件对应,叫做计算内存。

以上所谓“硬盘上有无对应数据”的前提是:计算内存、非计算内存是操作系统的分类,所以操作系统知道硬盘上有对应,才叫非计算内存。虽然任何数据库的内存占用绝大部分是磁盘缓冲,按理说其中的数据硬盘上有对应,但是,这些内存是数据库管理的,操作系统只知道这些内存是DBMS主动向操作系统申请的,其中放的什么,操作系统并不知道,所以是计算内存

breakdown:
计算内存、非计算内存都是指物理内存占用,而物理内存的情况,由于VMM机制,是时刻在变化的,所以只能说某一瞬间,计算内存、非计算内存各占用多少。

●计算内存:
凡是进程/程序运行中用程序代码向操作系统申请的内存,全部是计算内存,也就是说除非这个程序运行起来,除了自身代码占用的内存,一点额外的内存也不用,否则它几乎必然会造成计算内存占用的。说“几乎”,是因为计算内存、非计算内存都是指物理内存,如果一个程序申请了1MB内存,但一段时间没有用这部分内存,很可能在其他进程需要内存,且物理内存比较紧张时,按照LRU算法(Latest Recently Unused,最近最少使用),被操作系统部分或全部page out到paging space中,如果全部被page out了,可以说这个时刻,此进程没有使用计算内存。换句话说,就是程序申请了1MB内存,那么它在某一时刻占用的计算内存从0字节~1MB都有可能。

进程主动向操作系统申请分配的内存,从程序编码上来看,以C为例,典型的就是malloc,当然,还有程序语言中的隐式分配,反正对于操作系统来说都一样,例如char *string1="ABCDEFG"; int number=22222; 前者会导致自动向操作系统申请8个字节,后一个会申请一个字(两个字节)

当进程退出,或者意外崩溃,对于操作系统来说,它知道进程不在了,而进程申请的内存,操作系统明确知道是哪些的,在资源回收的过程中,会自动把这个进程申请的内存释放掉,这个过程是很快的。所以我们可以看到:如果计算内存高企,我们把应用一停,也就是把使用计算内存最多的进程停止,计算内存占用率立刻就下来了。


●非计算内存:
操作系统明确知道这部分内存的用途是放硬盘对应数据的,所以,显然这部分内存不是任何进程可以控制,也就是说不可能一个程序主动要求分配多少非计算内存或者释放多少。这部分完全是操作系统在直接管理:分配、记录状态、使用、释放,其他进程只可能用间接手段影响非计算内存,例如读写文件。

非计算内存我们常见的是如下用途:
——程序代码:当运行程序时,代码初始装入到物理内存的什么地方、重定位到什么地方,是操作系统管理的,它会记住程序代码放在物理内存什么地方,及其对应程序文件的位置。当程序代码占用的page frame需要被其他用途使用时,操作系统直接把这个page frame转给要使用这部分内存的进程,并记录标志,下次要是这个page原来的内容需要被引用,从对应程序文件中的对应位置读取进入物理内存。有些进程的某些计算内存占用是不能被替换的,例如执行VMM管理任务的操作系统核心进程,所以这部分会有操作系统机制设置标志,这个就是常说的pin住某些内存不准替换掉。
——磁盘访问缓冲区:这个不是常说的缓存区,缓存区(英文Cache)的目的是用来提高性能,而缓冲区(英文Buffer),是为了块设备访问特点的要求,比如硬盘块设备、逻辑卷块设备,必须读写的基本单位是一个块,一般是512字节,哪怕你只读写一个字节,也必须一次读进512字节,修改特定的那一个字节,然后再整个512字节块全部写出到硬盘。这就需要缓冲区的存在。缓冲区的总个数,是不固定的,操作系统可以根据同时在访问的块的数量随时调整。
——NFS访问缓冲区,原理基本同上;
——文件系统缓存:这个肯定是每一个字节都有硬盘文件对应的,显然是非计算内存。

作者: larryh   发布时间: 2008-06-19

谢谢老大,这种好贴子要学习

作者: lj_cd   发布时间: 2008-06-19

学习学习......多谢

作者: Surmount   发布时间: 2008-06-19

妙妙妙~~

作者: 俊俊   发布时间: 2008-06-19

顶 小黄顶老黄!!

作者: giant#kenh   发布时间: 2008-06-19

我的理解:

计算内存 -- Work segment
临时的;没有对应的持久磁盘存储位置;
一个进程结束,将释放物理和分页空间;
当空闲物理内存较少时,将page out到分页空间,以帮助释放更多物理内存

非计算内存 -- Persistent segment
持久段;在磁盘上有持久存储位置
数据文件or exe程序通常都映射为非计算内存;
数据文件:jfs、jfs2、nfs等

所以,当物理内存较少,计算内存将page out到pagingsapce,主机性能下降,这就是我们通常看到的内存瓶颈
我们需要保护计算内存,限制非计算内存,这是我们愿意看到的情况

AIX5.3以前的调整参数方法:maxperm%=maxclient%设置较低通常在20%左右
                                       minperm%设置的更低一点,通常可以是maxperm%的一半5%-10%

AIX5.3以后的调整参数方法:maxperm%=maxclient%设置的比较高90%左右
                                      minperm%还是设置的比较低,通常可以设置为5%-20%左右
                                      lru_file_repage=0

而lru_file_repage=1是AIX系统的default的值

lru_file_repage参数存在的意义:
1、是否应该考虑VMM重分页计数
2、替换什么类型的内存

当lru_file_repage=0的时候将只替换非计算内存,这显然达到了我们需要保护计算内存的目的

最近看了些资料,发现AIX5.3相对于以前的版本在多方面有提高和改变
绝对是一个好版本,不得不佩服IBM开发人员

[ 本帖最后由 lzolder 于 2008-6-19 16:47 编辑 ]

作者: lzolder   发布时间: 2008-06-19

就是黄上加黄!!

作者: giant#kenh   发布时间: 2008-06-19

非计算内存在开通ftp或者nfs服务的时候, 可能会影响到oracle内存性能.
当然了,象我, 条件不允许, 生产库的小鸡又不能随便动, 郁闷。

作者: 弱智   发布时间: 2008-06-19

是啊!!最近也一直在看这些东西!!觉得原理清楚很重要!!

作者: kingdanis   发布时间: 2008-06-19

跟着老大学习。

作者: 五“宅”一生   发布时间: 2008-06-19

有一点似乎需要纠正:

对于AIX ....可执行程序文件的代码段 属于计算内存
虽然对于这些段来说(代码 段和初始数据段) 其实是有文件部分在磁盘上对应的...但是最后还是会变成计算内存
这里有个转化的概念 OS 的Loader在装入可执行文件时...因为从disk 装入 ...这时所使用的还是属于NonComp..
一旦发生指令预取的page fault....则NonComp会转为Comp

pageOut去swapdevice的pages 对AIX叫WorkingStoragePages
所有的WorkingStoragePages都是Comp
然而不是所有的Comp都是WorkingStoragePage

应该说 Disk上有文件对应的就叫PermanentStoragePages....无文件对应的叫WorkingStoragePages

作者: FromHell   发布时间: 2008-06-19

黄老大出手,必属精品

作者: darkbug   发布时间: 2008-06-19

对不起,各位老大,水一下。


程序中
char *string1="ABCDEFG"; int number=22222;
属于初始化定义,也就是static的代码,到底是计算内存还是非计算内存,看以后是否有改写,由编译程序在编译的时候决定到低是什么。如果以后虽然有引用,但是没有改写,则在程序代码段,非计算内存,例如类似char *string2; string2=string1的引用,其实这个变量是个常量,ABCDEFG保存在代码段中,非计算内存,string1作为指针本身并不存在,因为指向是个常量,程序可以优化,把这个指针省略掉。

如果以后有改写,例如string1=string2;则在程序初始化会在堆中申请空间,也就是计算内存,同时程序代码段还是有该常量ABCDEFG, 22222,这部分还是非计算内存。

-----------
另外非计算内存并非完全可以丢弃,其中还有是否dirty,如果dirty,等同于计算内存处理,我还没有证据说明aix足够聪明到对于dirty的非计算内存会直接写磁盘原数据区还是写paging space,但以我个人推断,由于写磁盘数据区的是syncd,而处理pagingspace的是swap,两个截然不同的进程,他们在那么短暂的时间内,没有道理会相互通信,而且很有可能死锁,最好的办法就是dirty非计算内存完全等同于计算内存,paging到交换区。------------------
以上一段严重错误,(又是中午吃多了惹得祸,今天老板请吃自助餐)。经过larry老大当头棒喝,醍醐灌顶,七窍顿开!lrud是唯一的对内存进行检验的程序,而是否sync到磁盘或者交换区,syncd自己是不管的,它尊从内存页标记,因此不会出现两个程序争相处理一块内存的情况。再次感谢larry老大高风亮节,不耻屈尊与我等小辈讨论!不过经过刚刚专研,发现依然有疑惑,很多说法比较模糊,继续研究之中。预知后事如何,请看下集。。。

---------------------------------------------

由此,如果有大量的数据文件改写操作,例如copy,tar的目标文件,都会造成内存消耗,而且无法通过参数优化,只能增加syncd的写操作频繁程度或者增加并行数来解决。

-------------------
这段没有大问题,但前提条件正如larry老大所说,系统有足够的fremem的时候才会等待syncd被动刷新,否则lrud会主动调用syncd刷新,由于有fremem存在,通常不会系统有太大影响,优化不优化没什么意义,除非此时系统紧跟(在几分钟之内)着要进行大量申请内存的操作,例如load数据等批量操作、启动数据库等等,由于系统会lazy清理内存,只有申请的时候才会清理,所以后续程序会稍慢,如果非常必要(就差几分钟,一般没必要),可以主动进行内存清理,把用于文件系统的内存writeback,并释放。

释放的方式有:
1.删除刚刚进行操作的大文件,文件没了,内存中的cache就没了,自然变成fremem
2. 抖动系统,就是更改maxfre, minfre之类的参数,改成很大的值,然后再改回来。

最后感谢一次Larry老大,您的光辉形象将永远成为激励我们前进的原动力!

[ 本帖最后由 orian 于 2008-6-20 07:21 编辑 ]

作者: orian   发布时间: 2008-06-20

跟着老大水

作者: giant#kenh   发布时间: 2008-06-20

原帖由 orian 于 2008-6-20 00:21 发表
另外非计算内存并非完全可以丢弃,其中还有是否dirty,如果dirty,等同于计算内存处理,我还没有证据说明aix足够聪明到对于dirty的非计算内存会直接写磁盘原数据区还是写paging space,但以我个人推断,由于写磁盘数据区的是syncd,而处理pagingspace的是swap,两个截然不同的进程,他们在那么短暂的时间内,没有道理会相互通信,而且很有可能死锁,最好的办法就是dirty非计算内存完全等同于计算内存,paging到交换区。


syncd只是确保flush文件系统cache的最后一道防线,缺省syncd间隔是60秒,这中间syncd肯定是不干活的,但我们知道,文件系统cache必须以60秒进行flush,而中间绝对不commit任何cache page,这显然不符合常理。

当遇到dirty的fs cache page,是一定会自动先flush它们的。

以下说法来自AIX Information Center:

文件同步性能调整

JFS 的非顺序文件 I/O 会一直存储在内存中直到满足一定条件:

空闲列表缩小到 minfree,以致需要进行页替换。
syncd 守护程序按固定调度间隔刷新页。
执行了 sync 命令。
随机后写在达到随机后写阈值后清空脏页面。

顺序后写
如果簇的所有 4 页都是脏页,那么只要修改了下一个分区中的页,会调度将该簇中的 4 个脏页写入磁盘。如果不具备这一功能,那么直到 syncd 守护程序运行前,该页都会留存于内存,导致可能的 I/O 瓶颈和文件碎片。

缺省情况下,一个 JFS 文件划分成 16 KB 大小的分区或 4 页。每一个这样的分区被称为一簇。

VMM 用于充当阈值的簇数是可调整的。缺省值是一簇。使用 ioo -o numclust 命令增大 numclust 参数可延迟后写入。

对于增强型 JFS,ioo -o j2_nPagesPerWriteBehindCluster 命令用来指定每次调度的页数,而不是簇数。增强型 JFS 簇的缺省页数为 32,意味着增强型 JFS 的缺省大小为 128 KB。


随机后写
后写功能提供了这样一种机制,即当给定文件在内存中的脏页数超过规定阈值后,那么会调度所写的后续页面以写到磁盘上。

可能存在一些应用程序执行大量的随机 I/O,即 I/O 模式不满足后写算法的要求,因而导致所有页面驻留在内存中,直到 syncd 守护程序运行为止。如果应用程序修改了内存中的很多页面,那么在 syncd 守护程序发出 sync() 调用时,这会使得向磁盘写入大量页。

将 ioo 命令与 JFS maxrandwrt 参数一起使用,可调整阈值。缺省值为 0,表示随机后写是禁用的。将该值增加到 128 表示一旦文件驻留于内存的页达到 128 页,随后的任何脏页都将被调度写入磁盘。而这些页将在调用 sync() 后刷新。

对于增强型 JFS,ioo 命令选项 j2_nRandomCluster(-z 标志)和 j2_maxRandomWrite(-J 标志)用于调整随机后写。两个选项缺省值都为 0。增强型 JFS 的 j2_maxRandomWrite 选项和 JFS 的 maxrandwrt 功能相同。即它限定了每个文件可以留在内存中的脏页数。j2_nRandomCluster 选项指定了可以被视为随机的两次连续写入之间的簇数。



也就是说:
一个规则先说,这是前提:当一个fs cache page必须被另外使用时,一定是minfree已经达到了,否则系统只用从free list中取未用页来用即可。
●顺序后写造成的dirty page,当真正需要用到这些页时,minfree已经达到,而minfree达到时,一定会做先做commit dirty page的事情,所以不用占用paging space;
●缺省情况下,随机后写完全是关闭的,所以随机后写不会导致fs cache被使用,也就不可能产生dirty
●非缺省情况下,随机后写打开,那么情形同顺序后写。

所以您设想的dirty fs cache page需要换出到paging space的可能性并不存在。

[ 本帖最后由 larryh 于 2008-6-20 01:36 编辑 ]

作者: larryh   发布时间: 2008-06-20

高手!

我明天试试。

作者: orian   发布时间: 2008-06-20

原帖由 FromHell 于 2008-6-19 21:54 发表
对于AIX ....可执行程序文件的代码段 属于计算内存
虽然对于这些段来说(代码 段和初始数据段) 其实是有文件部分在磁盘上对应的...但是最后还是会变成计算内存
这里有个转化的概念 OS 的Loader在装入可执行文件时...因为从disk 装入 ...这时所使用的还是属于NonComp..
一旦发生指令预取的page fault....则NonComp会转为Comp


这一点,我倒没有看到有足够详细的官方资料来证明是或否

由此我引申想到两个有趣的问题:

1、某个页当前属于非计算内存还是计算内存,是否有专用的页标志来标明?我怀疑没有,因为IBM自己,都可能对内存页的那么多种用途到底算什么类型没有完全一致意见(除了典型的,占用量大的类型没有什么异议外)。比如nmon和topas显示的非计算内存和计算内存比例就不同。



2、这个更加有趣,而且有兴趣有精力的可以做做试验(需要POWER汇编的知识,至少可以查看特定代码的十六进制数据体现是什么,以在内存中定位出来,我没做)。有没有用户进程可访问的非计算内存?按照概念来说不应该有。那么如果用户进程去写非计算内存,应当会被操作系统发现越权访问不属于自己的内存,而把它干掉同时产生coredump。

如果您说的代码实际被引用到,会导致其转化为计算内存这一点,确实是AIX的标准行为,那么这个计算内存算不算这个进程自有?

这样会有这么几种情况:
●代码已经被执行过,所以它是计算内存:
如果它属于用户进程自有:自然这个进程可以修改已经被执行过的自身代码——可以设计一个试验来验证;
如果它不属于用户进程,则必然属于系统进程:这个进程修改已经被执行过的自身代码的尝试将导致coredump;
●代码尚未被执行过,所以它是非计算内存:
非计算内存不应该属于进程自有,所以试图修改它会造成coredump。

作者: larryh   发布时间: 2008-06-20

又要翻船

在infocenter找到明确说明:
Pages that are part of working segments are written to paging space; persistent segments are written to disk.(不过没有写是paging space还是file,还有机会。。。)

中午吃多了。。。嗨,怎么没想起来lrud是罪魁祸首,它会根据page情况调用磁盘写,否则也不会猜想两个进程争相刷新磁盘。。。

[ 本帖最后由 orian 于 2008-6-20 07:25 编辑 ]

作者: orian   发布时间: 2008-06-20

好帖子,学习了

作者: sugo   发布时间: 2008-06-20

学习学习

作者: 小猪   发布时间: 2008-06-20

原帖由 larryh 于 2008-6-20 02:40 发表
1、某个页当前属于非计算内存还是计算内存,是否有专用的页标志来标明?我怀疑没有,因为IBM自己,都可能对内存页的那么多种用途到底算什么类型没有完全一致意见(除了典型的,占用量大的类型没有什么异议外)。比如nmon和topas显示的非计算内存和计算内存比例就不同。

2、这个更加有趣,而且有兴趣有精力的可以做做试验(需要POWER汇编的知识,至少可以查看特定代码的十六进制数据体现是什么,以在内存中定位出来,我没做)。有没有用户进程可访问的非计算内存?按照概念来说不应该有。那么如果用户进程去写非计算内存,应当会被操作系统发现越权访问不属于自己的内存,而把它干掉同时产生coredump。

如果您说的代码实际被引用到,会导致其转化为计算内存这一点,确实是AIX的标准行为,那么这个计算内存算不算这个进程自有?

这样会有这么几种情况:
●代码已经被执行过,所以它是计算内存:
如果它属于用户进程自有:自然这个进程可以修改已经被执行过的自身代码——可以设计一个试验来验证;
如果它不属于用户进程,则必然属于系统进程:这个进程修改已经被执行过的自身代码的尝试将导致coredump;
●代码尚未被执行过,所以它是非计算内存:
非计算内存不应该属于进程自有,所以试图修改它会造成coredump。


发扬一不怕死,二不怕水,死猪不怕开水烫的精神,继续水。偷偷跟您说一声,为了保证灌水质量,我连晚饭都没吃,只喝水!力争保持清醒!忽然想起来,刚说了一句,现在LU高手越来越多,保不准什么时候就被一刀毙命!乌鸦嘴啊!

以下来自infocenter和我自己的理解,请大家多多水场。
http://publib.boulder.ibm.com/in ... _memory_mngment.htm

VMM管理将memory分成page,缺省page大小4KB,但aix操作系统支持更大的page,例如16M,但对于非4k的page,aix不能处理page in/out,只能将其pin在real memory中,aix中每256M的memory只能采用一种page size(aix支持混合使用),而且不需要重新启动,(需要预先将vmo参数large_page_heap_size=1以允许其它page),只需更改vmo参数到需要的大小,。但注意,使用其他大小的 page,不能交换。 与vmm不同, real memory (RAM)只有4k page, vmm管理程序需要将其page与real memory的4k对应(或者与磁盘交换区对应,就是page out出去了)。

vmm使用一些算法来进行对应。
Virtual-memory segments分为persistent segments 或者 working segments.
Virtual-memory segments同时还被分为computational or file memory
如果需要访问的Virtual-memory pages不在real memory,则引起page fault中断
Page faults又可能是new-page faults或者repage faults,最近一段时间(这个时间长短好像是lrud扫描完一遍内存pool的时间,有待确认。lrud不停地循环扫描内存pool,内存pool的大小根据机器拥有的物理内存多少和cpu数量有关,vmstat -v可以看到memory pool的数量,每个pool对应lrud的一个线程)第一次访问此页是new page fault,如果在这段时间第二次发生此page faults,则是repage faults。如果发生repage fault,系统会记录下来vmstat 1 的re一项既是。

Persistent和working segments
Persistent内存页如larry老大所说,就是在磁盘上有对应的,无论程序,数据文件还是cache(其实也是为数据文件准备的),
working segment是临时生成,例如malloc申请的。但由于单位是segment(256M),所以并不能按照4k断定那个是persistent,那个是working,而是vmm根据内存申请的特点来存放对应的page(我猜想,不确定,有待探讨)。也就是说,系统一定知道那些page是persistent,那些是working,因为这些page在初始化使用的时候,是在不同的段里面申请的!如果读写文件,vmm就在persistent segment分配page给请求者(打开文件通常由lvm内核操作,所以是系统调用),而程序通过malloc申请,即使保存的是文件的一部分(通过memcpy过来),但系统依然认为是working,在working段分配。

如果persistent里面的page被修改并且不能在real memory保存(什么情况下不能保存?待确定),则vmm将其写回到磁盘上对应的数据文件区。如果没被修改,则直接丢弃,不需要io,以后再有需求,重新读回来,因为磁盘上有对应文件(数据)。

c程序在执行的时候,操作系统vmm会自动分配stack/data段(working),heap段(working), program text段(persistent), shared lib段(persistent),每段256M,但只是一个虚拟空间,程序真正使用的时候,才会占据一个又一个4k,才会对应到real memory

Working segments是个临时区域,仅仅存活于程序执行期间,磁盘上也没有对应的数据文件。一点例外,系统内核的text和shared library本来应当保存在persistent段(因为内核也是程序,而程序的这些区域应当是persistent内存),但是他们也被算作working的,难道是防止系统运行过程中系统内核文件被误删除直接导致系统崩溃?而给大家留个缓冲时间,因为这些文件不会再从磁盘读入,只读一次,以后即使内存不够,也不会如同其他程序文件直接丢弃,而是交换到paging space! 推论:如果误删除了系统内核文件(限于执行文件和调用库,参数文件不算),千万别停机,系统还会正常工作!想办法还能从内存中找回来。

Persistent-segment还有更多的类型。Client segments 是用于远程文件,例如nfs mount过来的,这些page如果需要交换出去,则写回原位置或者丢弃(如果没有修改),而不会交换到交换区(我印象中4.3.3似乎是写本地交换区,估计是现在认为网络足够快了)。Journaled和deferred segments是persistent segments,必须进行原子操作写(原子操作大家都知道,就是同时只允许一个线程进行写,别的必须等待,不能并行写) 如果 journaled或者deferred segment需要从real memory偷页 (paged out), it must be written to disk paging space unless it is in a state that allows it to be committed (written to its permanent file location).

这是真正的疑点所在,哪些数据属于Journaled和deferred?我猜想是jfs的inode之类的数据,deferred呢?不确定。先放到这,回去找aix kernal internal继续专研。

Computational和file memory
Computational memory也就是computational pages, 包含working-storage segments或者program text (executable files) segments. 也就是说计算内存包括working段或者程序代码。 又出现疑点,程序代码以往我是当成非计算内存的,难道又疏忽了。。。?

file memory是所有其他的内存页,交换到自己原有对应的文件,这没什么说的。

但愿是5.3与以往版本有出入,否则误人子弟,诲人不倦啊!专研几天先。

多谢Larry老大给我们指出了一条康庄大道,道上还堆砌了无数荆棘。。。

作者: orian   发布时间: 2008-06-20

  救命啊··越看越糊涂。 唉··小生根基尚浅,来日再来拜读

作者: axisman   发布时间: 2008-06-20

欢迎黄老大和orian继续探讨,以致我等可以偷得一招办式

作者: xuandhe   发布时间: 2008-06-20

这种底层的探讨,我只能学习

作者: lj_cd   发布时间: 2008-06-20

orian太JB深入了,抗不住了

作者: larryh   发布时间: 2008-06-20

老大,别逗我了,就是infocenter...

不过,真的感谢,我以前觉得我清楚了,本贴如冬日春雷,振聋发聩啊!昨天好好又看了一遍,发现又有不少疑惑。自我解嘲一点,5.3新TL变了不少;自我反省一点,将近3年没看了!

这周再看一遍aix 5.3, 6.1 WN, 也许能找到一些蛛丝马迹。

作者: orian   发布时间: 2008-06-20

原帖由 larryh 于 2008-6-20 01:34 发表


syncd只是确保flush文件系统cache的最后一道防线,缺省syncd间隔是60秒,这中间syncd肯定是不干活的,但我们知道,文件系统cache必须以60秒进行flush,而中间绝对不commit任何cache page,这显然不符合常理 ...

于宁斌那本书上提到过,但是没有那么详细! 有可能于宁斌是抄ibm information 上的!

作者: giant#kenh   发布时间: 2008-06-20

定时启动syncd是被动刷新,但memory dirty到一定程度会触发主动刷新,larry老大介绍的很详细了。好像jfs, jfs2不同,我正在研究

作者: orian   发布时间: 2008-06-20

jfs2用的是client段,这个和jfs不同,也就是说应当和NFS的处理方法完全一样了。至于fs cache在NFS和JFS之间表现有什么不同我还不清楚

作者: larryh   发布时间: 2008-06-20

原帖由 larryh 于 2008-6-20 21:12 发表
jfs2用的是client段,这个和jfs不同,也就是说应当和NFS的处理方法完全一样了。至于fs cache在NFS和JFS之间表现有什么不同我还不清楚

黄老大能详细指点一下?

作者: giant#kenh   发布时间: 2008-06-20

永久存储

永久存储分页是一些包含永久数据(也就是说,重新启动后仍然存在的数据)的分页。这种永久数据就是文件数据。因此,永久存储分页就是缓存在内存中的部分文件。

当经过修改的永久存储分页需要换出(从内存移动到磁盘)的时候,会将它写入到文件系统中。如前所述,可以直接释放没有经过修改的永久存储分页,无需将其写入到文件系统中,因为文件系统包含该数据的原始副本。

例如,如果一个应用程序正在读取某个文件,那么该文件数据将缓存于永久存储分页的内存中。这些永久存储分页没有经过修改,这意味着并没有在内存中对这些分页进行修改。因此,内存中的永久存储分页与磁盘中的文件数据完全相同。当 AIX 需要清空内存的时候,它只需要“释放”这些分页即可,而不将任何内容写入到磁盘。如果应用程序对某个文件进行写操作(而不是读操作),那么永久存储分页将是“经过修改的”,并且 AIX 必须在释放这些分页之前将其刷新到磁盘。

您可以将永久存储分页划分为两种子类型:

客户端分页
非客户端分页
非客户端分页是一些包含缓存的日志文件系统 (JFS) 文件数据的分页。非客户端分页有时也称为持久性分页。客户端分页是一些包含所有其他文件系统(例如,JFS2 和网络文件系统 (NFS))的缓存数据的分页。 ibm developer works上的!

作者: giant#kenh   发布时间: 2008-06-20

正好要写aix 未公开的秘密,今天就把内存这个问题终结吧。。。哈哈,口气有点大,我没说我终结啊!等待黄老大、农老大、鸡老大、红旗老大、void老大、beginner老大以及各位隐形埋名的世外高人老大总结

鉴于细节太多,本文为续,只针对以前疑问。具体请参考以前讨论。本文内容引自inforcenter, developerworks(为主,假定其为真实)及其它google搜索结果(为辅,参考),并且时间为今天,版本是5.3(以后ibm可能更新算法,所以不能确认永远如此)

page 虽然可以有超过4k的内存page,但为了简化讨论,一下均指4k。

PFT page frame table, 这是物理内存分配、状态表。所有物理内存都在表中有对应,大概4k的page用8位标记(这个不确认,还没来得及查找信息)。其中有内存地址、内存类型(分别是Working, Persistent, Client类型,这回答了Larry的问题)、最近是否被访问(reference)、是否被修改标记。

当由于程序看到的是全部vmm,因此无论申请内存还是访问内存,都会发生vmm地址和real mem地址的转换,这个是cpu中硬件完成,如果转换的地址不在real mem中,则发生mem fault,并触发内核处理,内核将在free memory中申请一块空间,并把需要的vmm数据读到此处(如果需要读入,如果新申请,当然就不用读入了)

根据一些参数,aix维护一个free memory的列表,这个已经讨论多次,暂时不提。如果free memory不足,试图释放一些real memory内存出来。reallrud首先开始扫描物理内存页(real memory=physical memory),检查此page最近是否被referenced,如果没有被reference,立刻释放,而并在第一次扫描的时候已经被reference,则清掉reference标记。物理内存被分为若干bucket,大小为vmo中lrubucket界定,缺省512M,第一次扫描完某个bucket之后,找不到可释放内存(这句话不确定,也可能无论怎样都扫描两遍),则重新再扫描一遍这个bucket,如果某页依然没被referenced,则释放。这两遍扫描的时间就是给内存是否被频繁referenced的缓冲时间,内存从来没reference,立刻释放,如果被reference过,则等一小段时间,再看。此内存很忙,很有可能在两遍扫描期间被referenced,这样该内存也就被保留下来,不会释放,如果没有,则释放。这种两遍扫描的策略,最大限度增加了可被释放内存的数量(如果大部分内存都不能被释放,lrud效率就变得很低),但同时给可能被频繁访问的内存留有机会。

不知道这种策略是否最好,但肯定不错。通过以上分析,如果更改lru bucket的大小可以极大地影响第二次扫描的结果,也就是如果lru bucket越小,则内存被referenced的可能性越小(扫描间隔越小,时间大约是用cpu做一遍bucket大小内存hash比较的时间,缺省是128KB,估计远在1微秒以内)。对于高速cpu系统,例如在若干GHz这种cpu速度下,这个时间可能太小,在此期间,通常都不会被reference,所以也许很没效率,就是最近被访问的页面也被弄出去了。注意,这部分不一定对应的paging space操作,但很可能对应文件系统操作。一个建议,如果系统具有极其巨大的内存,例如几百G,并且使用文件系统,不妨尽可能增大lrubucket,最大可达到系统所拥有的所有物理内存页面。反之,可以减到最小65536。本人不负责后果!haha vmstat的sr, fr可以观看结果。


有关repage, aix保存一个repage history buffer, 如果在一段时间第二次发生此page faults,则是repage faults。如果发生repage fault,系统会记录下来vmstat 1 的re一项既是。系统依然用512M大约128KB的 history buffer空间,置于能保留多长时间,那就看此page fault发生的频率了,也就是如果系统reference page越多,page fault的可能性越大,history buffer也对应的时间也就越短。

此参数在系统没有严重设计问题的时候(例如内存过小,或者分配不合理),应当没什么用,但一旦有repage(同样不能有pi, po),一定要想办法避免。

memory pools影响lrud的并行度,如果cpu多,可以最多设置为cpu数量。

strict_maxperm 影响file cache,也就是限定了系统分配给filesystem cache的最大值为maxperm。


不写了,休息,休息一会。

[ 本帖最后由 orian 于 2008-6-21 07:23 编辑 ]

作者: orian   发布时间: 2008-06-21

我给你顶程哥!

作者: giant#kenh   发布时间: 2008-06-21

谁是程哥?

作者: 老农   发布时间: 2008-06-21

orian啊! 农哥装糊涂!

作者: giant#kenh   发布时间: 2008-06-21

你搞错了,那是另一只猪

作者: 老农   发布时间: 2008-06-21

热门下载

更多