linux怎么看linux的内存用这么多内存

二次元同好交流新大陆
扫码下载App
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!&&|&&
LOFTER精选
网易考拉推荐
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
要搞清楚这个问题,首先从top输出开始研究:top命令的输出中VIRT RES SHR这三列的意思我就不多解释了,man top 一下就明白了。VIRT 是进程使用的总的虚拟内存大小。RES 是常驻内存的大小(不能SWAP)。SHR 是共享内存的大小(包括共享库等)。然后看一下这几个值分别是从哪里来的?看了一下top命令的源代码,在m_linux.c中有这几个值的来源,简单说就是,这些值都是从/proc/$pid 下面读出来的:VIRT 是 /proc/$pid/stat 中的第23个数字。RES 是/proc/$pid/stat 中的第24个数字,但是要注意,这个是用页来表示的,所以需要成字节。SHR 是 /proc/$pid/statm 中的第三个数字,这个也是用页表示的,需要转换。总的虚拟内存大小不用管它,这里主要关注RES 和 SHR。查看linux内核代码可知RES的值获取方式如下:mm ? get_mm_rss(mm) : 0而get_mm_rss的定义如下:411 #define get_mm_rss(mm) \412 (get_mm_counter(mm, file_rss) + get_mm_counter(mm, anon_rss))而get_mm_counter也是一个宏,它获取了进程的内存结构体mm_struct中变量 _file_rss 和_anon_rss 成员。SHR的获取代码如下:*shared = get_mm_counter(mm, file_rss);由此可见:RES = mm_struct-&_file_rss + mm_struct-&_anon_rssSHR = mm_struct-&file_rss那么,file_rss 和anon_rss是怎么计算出来的?它们代表的意思又是什么?要彻底搞清楚这两个东西,直接从代码上解释比较麻烦,比较不容易说清楚。但是我们可以换个地方去寻找答案。我们发现,在/proc/$pid 下面还有其他的一些文件,那么这些文件又是什么意思呢?有没有用的上的呢?其实是有的。/proc/$pid/maps 这个文件描述了当前映射到进程的内存和它们的访问权限/proc/$pid/smaps 这个文件是对/proc/$pid/maps更详细的描述,包括了每个映射内存的大小和使用情况 (具体参见文档 kernel/Documentation/filesystems/proc.txt)在我的机器上将进程ID为50893,RES=2.3G的进程的 statm 和 smaps 保存到文件:cat /proc/50893/statm & statmcat /proc/50893/smaps & smaps[ocsrun@OCSPROXY1 lqb]$ cat statm1467525&602414& 0 559 0这里重点关注第二个数字,这个数是什么意思以及怎么取到的后面会说。[ocsrun@OCSPROXY1 lqb]$ grep Rss smaps |awk 'BEGIN {sum = 0;} {sum += $2} END{print sum}'2409656然后发现:602414 × 4K = 2409656K 与smaps中所有的Rss的和相等。而2409656 / 1024 / 1024 = 2.298 = 2.3G 这不就是RES的大小吗?现在来说statm 中的第二个数,这个数就是 file_rss + anon_rss,代码我就不贴了,参看/kernel/fs/proc/array.c 和 /kernel/fs/proc/task_mmu.c而smaps中所有的Rss,是遍历进程所有的虚拟映射链表,一个一个累加出来的。以下是相关结构体的片段。202 struct mm_struct {203 struct vm_area_struct * /* list of VMAs */134 struct vm_area_struct {135 struct mm_struct * vm_ /* The address space we belong to. */136 unsigned long vm_ /* Our start address within vm_mm. */137 unsigned long vm_ /* The first byte after our end address138 within vm_mm. */至此我们知道file_rss + anon_rss 就是进程所有映射的页面的大小,注意这里说的都是虚拟地址空间,而不是物理内存(当然也包括了一部分的物理内存)。前面那个关于file_rss 和 anon_rss的问题算是基本上搞清楚了,但是为什么有的进程的映射页面会突然变得很大呢?为了搞清楚这个问题,我们仔细查看一下smaps文件:仔细查看后发现,smaps里面包括了所有映射的动态库,heap,stack等等。当然也包括了共享内存。共享内存是以下面的方式而存在的:7f43df rw-s :04 8749063 /SYSV00c9b457 (deleted)Size: 5242880 kBRss: 2098384 kBPss: 1052946 kBShared_Clean: 541256 kBShared_Dirty: 1548472 kBPrivate_Clean: 7656 kBPrivate_Dirty: 1000 kBReferenced: 2098364 kBSwap: 0 kBKernelPageSize: 4 kBMMUPageSize: 4 kB而普通共享库是这样的:7f452c11d000-7f452c4c9000 r-xp :09 8172 /home/ocsrun/xerces-c/xerces-c-3.0.0/lib/libxerces-c-3.0.soSize: 3760 kBRss: 1336 kBPss: 93 kBShared_Clean: 1336 kBShared_Dirty: 0 kBPrivate_Clean: 0 kBPrivate_Dirty: 0 kBReferenced: 1336 kBSwap: 0 kBKernelPageSize: 4 kBMMUPageSize: 4 kB将上面共享内存的行移下来:7f43df rw-s :04 8749063 /SYSV00c9b457(deleted)该行的意思如下:第一列是(虚拟)地址映射空间,第二列是访问权限,第三列是偏移量,第四列是设备号,以主设备号:次设备号的方式显示,第五列是inode,最后一列是路径。这里为什么是deleted呢?因为对于共享内存来说,根本不存在实际的文件跟它对应。运行ipcs输出如下(部分输出):[ocsrun@OCSPROXY1 ~]$ ipcs------ Shared Memory Segments --------key shmid owner perms bytes nattch status0x00c9b455 8683525 ocsrun 660 0x00c9b456 8716294 ocsrun 660 0x00c9b457 8749063 ocsrun 660
50x00c9b45f 8781832 ocsrun 660 可以看到,在smaps中共享内存的inode是8749063,也就是ipcs显示的shmid,而key就是文件路径的后面一段。如上面所示,共享内存的映射有一个大于2G的,所以加上另外两块共享内存的映射,总的RES有2.3G也就不奇怪了。而关于共享内存的分配,多说两句:sys v shared memory实现,shmget基本就是在ramfs上写一个名字是SYSV&shm_key&的文件(这里是/SYSV00c9457),然后该文件的inode号是内核ipc核心数据结构的唯一id号,之后shmat基本就是mmap这个文件的过程,也就是说shmget返回的shmid其实就是用于存储内容的文件的inode编号。所以:Linux上top输出中RES和SHR的值比较高是没有关系的,因为可能大部分都是共享内存。top和ps等的输出中关于内存占用的部分都包括了共享内存/共享库等占用的虚拟内存空间。
阅读(5523)|
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
历史上的今天
loftPermalink:'',
id:'fks_',
blogTitle:'Linux上通过top查看进程的RES和SHR的值很高,表示进程(独)占用的内存很多吗?',
blogAbstract:'在Linux上通过top看到的RES和SHR的值很高,表示进程占用的内存很多吗?会有什么问题吗?要搞清楚这个问题,首先从top输出开始研究:top命令的输出中VIRT RES SHR这三列的意思我就不多解释了,man top 一下就明白了。VIRT 是进程使用的总的虚拟内存大小。RES 是常驻内存的大小(不能SWAP)。SHR 是共享内存的大小(包括共享库等)。然后看一下这几个值分别是从哪里来的?看了一下top命令的源代码,在m_linux.c中有这几个值的来源,简单说就是,',
blogTag:'源码',
blogUrl:'blog/static/',
isPublished:1,
istop:false,
modifyTime:0,
publishTime:2,
permalink:'blog/static/',
commentCount:0,
mainCommentCount:0,
recommendCount:0,
bsrk:-100,
publisherId:0,
recomBlogHome:false,
currentRecomBlog:false,
attachmentsFileIds:[],
groupInfo:{},
friendstatus:'none',
followstatus:'unFollow',
pubSucc:'',
visitorProvince:'',
visitorCity:'',
visitorNewUser:false,
postAddInfo:{},
mset:'000',
remindgoodnightblog:false,
isBlackVisitor:false,
isShowYodaoAd:false,
hostIntro:'',
hmcon:'0',
selfRecomBlogCount:'0',
lofter_single:''
{list a as x}
{if x.moveFrom=='wap'}
{elseif x.moveFrom=='iphone'}
{elseif x.moveFrom=='android'}
{elseif x.moveFrom=='mobile'}
${a.selfIntro|escape}{if great260}${suplement}{/if}
{list a as x}
推荐过这篇日志的人:
{list a as x}
{if !!b&&b.length>0}
他们还推荐了:
{list b as y}
转载记录:
{list d as x}
{list a as x}
{list a as x}
{list a as x}
{list a as x}
{if x_index>4}{break}{/if}
${fn2(x.publishTime,'yyyy-MM-dd HH:mm:ss')}
{list a as x}
{if !!(blogDetail.preBlogPermalink)}
{if !!(blogDetail.nextBlogPermalink)}
{list a as x}
{if defined('newslist')&&newslist.length>0}
{list newslist as x}
{if x_index>7}{break}{/if}
{list a as x}
{var first_option =}
{list x.voteDetailList as voteToOption}
{if voteToOption==1}
{if first_option==false},{/if}&&“${b[voteToOption_index]}”&&
{if (x.role!="-1") },“我是${c[x.role]}”&&{/if}
&&&&&&&&${fn1(x.voteTime)}
{if x.userName==''}{/if}
网易公司版权所有&&
{list x.l as y}
{if defined('wl')}
{list wl as x}{/list}linux free命令详解和使用实例(查看内存使用率)
作者:佚名
字体:[ ] 来源:互联网 时间:04-09 17:34:48
free命令可以显示Linux系统中空闲的、已用的物理内存及swap内存,及被内核使用的buffer。在Linux系统监控的工具中,free命令是最经常使用的命令之一
1.命令格式:
free&[参数]
2.命令功能:
free&命令显示系统使用和空闲的内存情况,包括物理内存、交互区内存(swap)和内核缓冲区内存。共享内存将被忽略
3.命令参数:
-b& 以Byte为单位显示内存使用情况。&
-k& 以KB为单位显示内存使用情况。&
-m& 以MB为单位显示内存使用情况。
-g&&&以GB为单位显示内存使用情况。&
-o& 不显示缓冲区调节列。&
-s&间隔秒数&& 持续观察内存使用状况。&
-t& 显示内存总和列。&
-V& 显示版本信息。&
4.使用实例:
实例1:显示内存使用情况
代码如下:freefree -gfree -m
代码如下:[root@SF1150 service]# freetotal used free shared buffers cachedMem: 8 0 63424-/+ buffers/cache: 07192Swap: 2&/p&
&p&[root@SF1150 service]# free -gtotal used free shared buffers cachedMem: 31 29 2 0 4 10-/+ buffers/cache: 14 17Swap: 31 1 29&/p&
&p&[root@SF1150 service]# free -mtotal used free shared buffers cachedMem:
8 11097-/+ buffers/cache: Swap:
free命令输出内容详细说明:
下面是对这些数值的解释:
total:总计物理内存的大小。
used:已使用多大。
free:可用有多少。
Shared:多个进程共享的内存总额。
Buffers/cached:磁盘缓存的大小。
第三行(-/+&buffers/cached):
used:已使用多大。
free:可用有多少。
第四行是交换分区SWAP的,也就是我们通常所说的虚拟内存。
区别:第二行(mem)的used/free与第三行(-/+&buffers/cache)&used/free的区别。&这两个的区别在于使用的角度来看,第一行是从OS的角度来看,因为对于OS,buffers/cached&都是属于被使用,所以他的可用内存是2098428KB,已用内存是KB,其中包括,内核(OS)使用+Application(X,&oracle,etc)使用的+buffers+cached.
第三行所指的是从应用程序角度来看,对于应用程序来说,buffers/cached&是等于可用的,因为buffer/cached是为了提高文件读取的性能,当应用程序需在用到内存的时候,buffer/cached会很快地被回收。
所以从应用程序的角度来说,可用内存=系统free&memory+buffers+cached。
如本机情况的可用内存为:
8428KB+4545340KB+KB
接下来解释什么时候内存会被交换,以及按什么方交换。&
当可用内存少于额定值的时候,就会开会进行交换.如何看额定值:&
命令:cat&/proc/meminfo&
代码如下:[root@SF1150 service]# cat /proc/meminfoMemTotal:
kBMemFree: 2096700 kBBuffers: 4545340 kBCached:
kBSwapCached: 1896080 kBActive:
kBInactive: 7427836 kBHighTotal: 0 kBHighFree: 0 kBLowTotal:
kBLowFree: 2096700 kBSwapTotal:
kBSwapFree:
kBDirty: 164 kBWriteback: 0 kBAnonPages:
kBMapped: 20748 kBSlab: 590232 kBPageTables: 34200 kBNFS_Unstable: 0 kBBounce: 0 kBCommitLimit:
kBCommitted_AS:
kBVmallocTotal:
kBVmallocUsed: 278840 kBVmallocChunk:
kBHugePages_Total: 0HugePages_Free: 0HugePages_Rsvd: 0Hugepagesize: 2048 kB
交换将通过三个途径来减少系统中使用的物理页面的个数: &
1.减少缓冲与页面cache的大小,&
2.将系统V类型的内存页面交换出去, &
3.换出或者丢弃页面。(Application&占用的内存页,也就是物理内存不足)。&
事实上,少量地使用swap是不是影响到系统性能的。
那buffers和cached都是缓存,两者有什么区别呢?
为了提高磁盘存取效率,&Linux做了一些精心的设计,&除了对dentry进行缓存(用于VFS,加速文件路径名到inode的转换),&还采取了两种主要Cache方式:Buffer&Cache和Page&Cache。前者针对磁盘块的读写,后者针对文件inode的读写。这些Cache有效缩短了&I/O系统调用(比如read,write,getdents)的时间。
磁盘的操作有逻辑级(文件系统)和物理级(磁盘块),这两种Cache就是分别缓存逻辑和物理级数据的。
Page&cache实际上是针对文件系统的,是文件的缓存,在文件层面上的数据会缓存到page&cache。文件的逻辑层需要映射到实际的物理磁盘,这种映射关系由文件系统来完成。当page&cache的数据需要刷新时,page&cache中的数据交给buffer&cache,因为Buffer&Cache就是缓存磁盘块的。但是这种处理在2.6版本的内核之后就变的很简单了,没有真正意义上的cache操作。
Buffer&cache是针对磁盘块的缓存,也就是在没有文件系统的情况下,直接对磁盘进行操作的数据会缓存到buffer&cache中,例如,文件系统的元数据都会缓存到buffer&cache中。
简单说来,page&cache用来缓存文件数据,buffer&cache用来缓存磁盘数据。在有文件系统的情况下,对文件操作,那么数据会缓存到page&cache,如果直接采用dd等工具对磁盘进行读写,那么数据会缓存到buffer&cache。
所以我们看linux,只要不用swap的交换空间,就不用担心自己的内存太少.如果常常swap用很多,可能你就要考虑加物理内存了.这也是linux看内存是否够用的标准.
如果是应用服务器的话,一般只看第二行,+buffers/cache,即对应用程序来说free的内存太少了,也是该考虑优化程序或加内存了。
实例2:以总和的形式显示内存的使用信息
命令:free&-t&
代码如下:[root@SF1150 service]# free -t total used free shared buffers cachedMem: 8 0 64324-/+ buffers/cache: 04752Swap: 2Total: 60[root@SF1150 service]#
实例3:周期性的查询内存使用信息
命令:free&-s&10
代码如下:[root@SF1150 service]# free -s 10total used free shared buffers cachedMem: 4 0 64380-/+ buffers/cache: 05304Swap: 2total used free shared buffers cachedMem: 0 0 64388-/+ buffers/cache: 05908Swap: 2
每10s&执行一次命令
大家感兴趣的内容
12345678910
最近更新的内容您所在的位置: &
如何手工释放linux内存?
如何手工释放linux内存?
当在Linux下频繁存取文件后,物理内存会很快被用光,当程序结束后,内存不会被正常释放,而是一直作为caching。这个问题,貌似有不少人在问,不过都没有看到有什么很好解决的办法。那么我来谈谈这个问题。
 当在Linux下频繁存取文件后,物理内存会很快被用光,当程序结束后,内存不会被正常释放,而是一直作为caching。这个问题,貌似有不少人在问,不过都没有看到有什么很好解决的办法。那么我来谈谈这个问题。
一、通常情况
先来说说free命令:
[root@server&~]#&free&-m &&total&used&free&shared&buffers&cached &&Mem:&249&163&86&0&10&94 &&-/+&buffers/cache:&58&191 &&Swap:&511&0&511&
total&内存总数 &&used&已经使用的内存数 &&free&空闲的内存数 &&shared&多个进程共享的内存总额 &&buffers&Buffer&Cache和cached&Page&Cache&磁盘缓存的大小 &&-buffers/cache&的内存数:used&&&buffers&&&cached &&+buffers/cache&的内存数:free&+&buffers&+&cached &&可用的memory=free&memory+buffers+cached。&
有了这个基础后,可以得知,我现在used为163MB,free为86MB,buffer和cached分别为10MB,94MB。
那么我们来看看,如果我执行复制文件,内存会发生什么变化.
[root@server&~]#&cp&-r&/etc&~/test/ &&[root@server&~]#&free&-m &&total&used&free&shared&buffers&cached &&Mem:&249&244&4&0&8&174 &&-/+&buffers/cache:&62&187 &&Swap:&511&0&511&
在我命令执行结束后,used为244MB,free为4MB,buffers为8MB,cached为174MB,天呐,都被cached吃掉了。别紧张,这是为了提高文件读取效率的做法。
为了提高磁盘存取效率,Linux做了一些精心的设计,除了对dentry进行缓存(用于VFS,加速文件路径名到inode的转换),还采取了两种主要Cache方式:Buffer Cache和Page Cache。前者针对磁盘块的读写,后者针对文件inode的读写。这些Cache有效缩短了 I/O系统调用(比如read,write,getdents)的时间。
那么有人说过段时间,linux会自动释放掉所用的内存。等待一段时间后,我们使用free再来试试,看看是否有释放?
[root@server&test]#&free&-m &&total&used&free&shared&buffers&cached &&Mem:&249&244&5&0&8&174 &&-/+&buffers/cache:&61&188 &&Swap:&511&0&511&
似乎没有任何变化。(实际情况下,内存的管理还与Swap有关)
那么我能否手动释放掉这些内存呢?回答是可以的!
二、手动释放缓存
/proc是一个虚拟文件系统,我们可以通过对它的读写操作做为与kernel实体间进行通信的一种手段。也就是说可以通过修改/proc中的文件,来对当前kernel的行为做出调整。那么我们可以通过调整/proc/sys/vm/drop_caches来释放内存。操作如下:
引用 &&[root@server&test]#&cat&/proc/sys/vm/drop_caches &&0 &&首先,/proc/sys/vm/drop_caches的值,默认为0。 &&引用 &&[root@server&test]#&sync&
手动执行sync命令(描述:sync 命令运行 sync 子例程。如果必须停止系统,则运行sync 命令以确保文件系统的完整性。sync 命令将所有未写的系统缓冲区写到磁盘中,包含已修改的 i-node、已延迟的块 I/O 和读写映射文件)
引用 &&[root@server&test]#&echo&3&&/proc/sys/vm/drop_caches &&[root@server&test]#&cat&/proc/sys/vm/drop_caches &&3 &&将/proc/sys/vm/drop_caches值设为3 &&引用 &&[root@server&test]#&free&-m &&total&used&free&shared&buffers&cached &&Mem:&249&66&182&0&0&11 &&-/+&buffers/cache:&55&194 &&Swap:&511&0&511&
再来运行free命令,会发现现在的used为66MB,free为182MB,buffers为0MB,cached为11MB。那么有效的释放了buffer和cache。
◎ 有关/proc/sys/vm/drop_caches的用法在下面进行了说明
引用 &&/proc/sys/vm/drop_caches&(since&Linux&2.6.16) &&Writing&to&this&file&causes&the&kernel&to&drop&clean&caches, &&dentries&and&inodes&from&memory,&causing&that&memory&to&become &&free. &&To&free&pagecache,&use&echo&1&&/proc/sys/vm/drop_&to &&free&dentries&and&inodes,&use&echo&2&&/proc/sys/vm/drop_ &&to&free&pagecache,&dentries&and&inodes,&use&echo&3&&&/proc/sys/vm/drop_caches. &&Because&this&is&a&non-destructive&operation&and&dirty&objects &&are&not&freeable,&the&user&should&run&sync&first.&
三、我的意见
上述文章就长期以来很多用户对Linux内存管理方面的疑问,给出了一个比较&直观&的回复,我更觉得有点像是核心开发小组的妥协。
对于是否需要使用这个值,或向用户提及这个值,我是有保留意见的:
1、从man可以看到,这值从2.6.16以后的核心版本才提供,也就是老版的操作系统,如红旗DC 5.0、RHEL 4.x之前的版本都没有;
2、若对于系统内存是否够用的观察,我还是原意去看swap的使用率和si/so两个值的大小;
用户常见的疑问是,为什么free这么小,是否关闭应用后内存没有释放?
但实际上,我们都知道这是因为Linux对内存的管理与Windows不同,free小并不是说内存不够用了,应该看的是free的第二行最后一个值:
-/+ buffers/cache: 58 191
这才是系统可用的内存大小。
实际项目中告诉我们,如果因为是应用有像内存泄露、溢出的问题,从swap的使用情况是可以比较快速可以判断的,但free上面反而比较难查看。
相反,如果在这个时候,我们告诉用户,修改系统的一个值,&可以&释放内存,free就大了。用户会怎么想?不会觉得操作系统&有问题&吗?
所以说,我觉得既然核心是可以快速清空buffer或cache,也不难做到(这从上面的操作中可以明显看到),但核心并没有这样做(默认值是0),我们就不应该随便去改变它。
一般情况下,应用在系统上稳定运行了,free值也会保持在一个稳定值的,虽然看上去可能比较小。
当发生内存不足、应用获取不到可用内存、OOM错误等问题时,还是更应该去分析应用方面的原因,如用户量太大导致内存不足、发生应用内存溢出等情况,否则,清空buffer,强制腾出free的大小,可能只是把问题给暂时屏蔽了。
我觉得,排除内存不足的情况外,除非是在软件开发阶段,需要临时清掉buffer,以判断应用的内存使用情况;或应用已经不再提供支持,即使应用对内存的时候确实有问题,而且无法避免的情况下,才考虑定时清空buffer。(可惜,这样的应用通常都是运行在老的操作系统版本上,上面的操作也解决不了)。
【编辑推荐】
【责任编辑: TEL:(010)】
关于的更多文章
Linux内存管理是Linux操作系统非常重要的一个部分,如何做好Linu
Linux界极具活力,面向不同的用户可以使用不同的Linux发行版,比如适合新手和游戏爱好者等。
开源技术的不断发展为IT人员的工作提供了便利,在开源
本专题总结了Apache软件基金会(简称ASF)中的十个命
日,Velocity China 2013 Web 性能与运维
本书是一本以示例形式直接面向应用的网络管理图书。书中以大量示例和大量实用网络管理与故障排除经验介绍了当前网络管理工作的各
51CTO旗下网站本博客微信公共账号:hadoop123(微信号为:hadoop-123),分享hadoop技术内幕,hadoop最新技术进展,发布hadoop相关职位和求职信息,hadoop技术交流聚会、讲座以及会议等。二维码如下:
1. 基本概念
(1)逻辑地址:指由程序产生的与段相关的偏移地址部分。在C语言指针中,读取指针变量本身值(&操作),实际上这个值就是逻辑地址,它是相对于你当前进程数据段的地址。
(2)线性地址:段中的偏移地址(逻辑地址),加上相应段的基地址就生成了一个线性地址。
(3)物理地址: 放在寻址总线上的地址。
(4)虚拟地址:保护模式下段和段内偏移量组成的地址,而逻辑地址就是代码段内偏移量,或称进程的逻辑地址。
(1) 虚拟内存:计算机系统内存管理的一种技术。它使得应用程序认为它拥有连续的可用的内存(一个连续完整的地址空间),而实际上,它通常是被分隔成多个物理内存碎片,还有部分暂时存储在外部磁盘存储器上,在需要时进行数据交换。与没有使用虚拟内存技术的系统相比,使用这种技术的系统使得大型程序的编写变得更容易,对真正的物理内存(例如RAM)的使用也更有效率。
(2) 物理内存:实际的内存。物理地址被分成离散的单元,成为页(page)。目前大多数系统的页面大小都为4k。
1.3 地址转换
Linux采用段页式管理机制,有两个部件用于地址转换:分段部件和分页部件。
(1) 分段部件:将逻辑地址转换为线性地址。分段提供了隔绝各个代码、数据和堆栈区域的机制,因此多个程序(任务)可以运行在同一个处理器上而不会互相干扰。
(2) 分页部件:将线性地址转换为物理地址(页表和页目录),若没有启用分页机制,那么线性地址直接就是物理地址。
2. 内存分配
Malloc,kmalloc 和vmalloc区别?
(1) kmalloc和vmalloc是分配的是内核的内存,malloc分配的是用户的内存。
(2) kmalloc保证分配的内存在物理上是连续的,vmalloc保证的是在虚拟地址空间上的连续。
(3) kmalloc申请的内存比较小,一般小于128 K。它是基于slab(内存池)的,以加快小内存申请效率。
3. 常见问题
(1) 调用malloc函数后,OS会马上分配实际的内存空间吗?
答:不会,只会返回一个虚拟地址,待用户要使用内存时,OS会发出一个缺页中断,此时,内存管理模块才会为程序分配真正的内存。
(2) 段式管理和页式管理的优缺点?
在段式存储管理中,将程序的地址空间划分为若干个段(segment),这样每个进程有一个二维的地址空间,相互独立,互不干扰。程序通过分段划分为多个模块,如代码段、数据段、共享段。这样做的优点是:可以分别编写和编译源程序的一个文件,并且可以针对不同类型的段采取不同的保护,也可以按段为单位来进行共享。段式存储管理的优点是:没有内碎片,外碎片可以通过内存紧缩来消除;便于实现内存共享。
在页式存储管理中,将程序的逻辑地址空间划分为固定大小的页(page),而物理内存划分为同样大小的页框(pageframe)。程序加载时,可将任意一页放人内存中任意一个页框,这些页框不必连续,从而实现了离散分配。这种管理方式的优点是,没有外碎片,且一个程序不必连续存放。这样就便于改变程序占用空间的大小。
页式和段式系统有许多相似之处。比如,两者都采用离散分配方式,且都通过地址映射机构来实现地址变换。但概念上两者也有很多区别,主要表现在: [1] 页是信息的物理单位,分页是为了实现离散分配方式,以减少内存的外零头,提高内存的利用率。或者说,分页仅仅是由于系统管理的需要,而不是用户的需要。段是信息的逻辑单位,它含有一组其意义相对完整的信息。分段的目的是为了更好地满足用户的需要。
[2] 页的大小固定且由系统决定,把逻辑地址划分为页号和页内地址两部分,是由机器硬件实现的。段的长度不固定,且决定于用户所编写的程序,通常由编译系统在对源程序进行编译时根据信息的性质来划分。
[3] 页式系统地址空间是一维的,即单一的线性地址空间,程序员只需利用一个标识符,即可表示一个地址。分段的作业地址空间是二维的,程序员在标识一个地址时,既需给出段名,又需给出段内地址。
(3) Malloc在什么情况下调用mmap?
从操作系统角度来看,进程分配内存有两种方式,分别由两个系统调用完成:brk和mmap(不考虑共享内存)。brk是将数据段(.data)的最高地址指针_edata往高地址推,mmap是在进程的虚拟地址空间中(一般是堆和栈中间)找一块空闲的。这两种方式分配的都是虚拟内存,没有分配物理内存。在第一次访问已分配的虚拟地址空间的时候,发生缺页中断,操作系统负责分配物理内存,然后建立虚拟内存和物理内存之间的映射关系。
在标准C库中,提供了malloc/free函数分配释放内存,这两个函数底层是由brk,mmap,munmap这些系统调用实现的。
默认情况下,malloc函数分配内存,如果请求内存大于128K(可由M_MMAP_THRESHOLD选项调节),那就不是去推_edata指针了,而是利用mmap系统调用,从堆和栈的中间分配一块虚拟内存。这样子做主要是因为brk分配的内存需要等到高地址内存释放以后才能释放(例如,在B释放之前,A是不可能释放的),而mmap分配的内存可以单独释放。
(4) 32位系统,通常情况下,最大虚拟地址和物理地址空间为多少?
不使用PAE情况下,最大虚拟地址和物理地址空间均为4G,若果使用PAE,最大虚拟地址仍为4G,而物理地址空间可变为64G(x86, 32为变36位)。
(5) 怎样实现malloc和free?
Malloc实现可考虑采用buddy算法+slob算法,free类似。
4. 参考资料
Linux Memory Management Notes:
内存段页式管理笔记:
虚拟地址、线性地址和物理地址的转换:
kmalloc、vmalloc、malloc的区别:
Linux中的物理和虚拟存储空间布局:
[百度分享]频繁分配释放内存导致的性能问题的分析
最近面试常被问到内存管理的一些基础知识,特整理此文,以作为这阶段面试的小总结。
原创文章,转载请注明: 转载自
本文链接地址:
作者:,作者介绍:
本博客的文章集合:
2 Comments to “Linux内存管理基本概念”

我要回帖

更多关于 怎么看linux的内存 的文章

 

随机推荐