注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

Tsecer的回音岛

Tsecer的博客

 
 
 

日志

 
 

为什么物理内存有剩余但是swap已用完  

2014-08-29 22:44:42|  分类: Linux内核 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
一、内存有剩余但是swap被使用或用完
在实际运行过程中,可以看到有些环境下,系统的物理内存还有剩余,但是swap已经被用完,当时最早看到这种情况的时候还是有点费解的,在网上搜索了下这种情况,在serverfault上给出了解释,大致是说,一个运行时间较长的系统,一些守护进程那些没有对应文件的页面会被逐渐的移动到swap中,这种现象是正常现象。在另一个帖子中,提到了swapiness配置对页面swap的影响
二、以某台服务器为例看下这个现象
cat /proc/*/smaps > /home/harry/allsysproc.smaps

egrep -n "Swap" harry/allsysproc.smaps   | grep -v "0 kB" | sort -nk 2 |tail -20

62002:Swap:                 16 kB
62362:Swap:                 16 kB
62722:Swap:                 16 kB
7390:Swap:                 16 kB
9334:Swap:                 16 kB
1102:Swap:                 28 kB
35326:Swap:                 28 kB
4450:Swap:                 28 kB
8518:Swap:                 28 kB
41878:Swap:                 32 kB
42466:Swap:                 44 kB
9694:Swap:                 48 kB
42286:Swap:                 76 kB
7450:Swap:                 76 kB
100570:Swap:                136 kB
100810:Swap:                152 kB
34870:Swap:                152 kB
35266:Swap:                212 kB
34858:Swap:                528 kB
35230:Swap:                848 kB
通过输出的行号,可以查找到这些swap所属的进程:
100525 00400000-0040f000 r-xp 00000000 ca:01 404881                             /sbin/udevd
100570:Swap:                136 kB
100810:Swap:                152 kB
34870:Swap:                152 kB
35266:Swap:                212 kB
34858:Swap:                528 kB
35230:Swap:                848 kB

00536000-0053a000 rw-p 00036000 ca:01 553097                             /usr/sbin/hald
  35221 7f7db33bd000-7f7db3492000 rw-p 00000000 00:00 0
  35222 Size:                852 kB
  35223 Rss:                   4 kB
  35224 Pss:                   4 kB
  35225 Shared_Clean:          0 kB
  35226 Shared_Dirty:          0 kB
  35227 Private_Clean:         0 kB
  35228 Private_Dirty:         4 kB
  35229 Referenced:            4 kB
  35230 Swap:                848 kB
  35231 KernelPageSize:        4 kB
  35232 MMUPageSize:           4 kB
  34825 00536000-0053a000 rw-p 00036000 ca:01 553097                             /usr/sbin/hald
  34849 00dc8000-00e5c000 rw-p 00000000 00:00 0                                  [heap]
  34850 Size:                592 kB
  34851 Rss:                  56 kB
  34852 Pss:                  56 kB
  34853 Shared_Clean:          0 kB
  34854 Shared_Dirty:          0 kB
  34855 Private_Clean:         0 kB
  34856 Private_Dirty:        56 kB
  34857 Referenced:           56 kB
  34858 Swap:                528 kB
  34859 KernelPageSize:        4 kB
  34860 MMUPageSize:           4 kB
就是说它们主要数据hald和udev这两个守护进程,它们开机之后运营,而且被访问的次数很少,大量匿名页面被swap到存储中。
三、swap的时机
try_to_free_pages--->>shrink_zones-->>shrink_zone-->>>shrink_active_list

if (sc->may_swap) {
long mapped_ratio;
long distress;
long swap_tendency;

if (zone_is_near_oom(zone))
goto force_reclaim_mapped;

/*
* `distress' is a measure of how much trouble we're having
* reclaiming pages.  0 -> no problems.  100 -> great trouble.
*/
distress = 100 >> min(zone->prev_priority, priority);

/*
* The point of this algorithm is to decide when to start
* reclaiming mapped memory instead of just pagecache.  Work out
* how much memory
* is mapped.
*/
mapped_ratio = ((global_page_state(NR_FILE_MAPPED) +
global_page_state(NR_ANON_PAGES)) * 100) /
vm_total_pages;

/*
* Now decide how much we really want to unmap some pages.  The
* mapped ratio is downgraded - just because there's a lot of
* mapped memory doesn't necessarily mean that page reclaim
* isn't succeeding.
*
* The distress ratio is important - we don't want to start
* going oom.
*
* A 100% value of vm_swappiness overrides this algorithm
* altogether.
*/
swap_tendency = mapped_ratio / 2 + distress + sc->swappiness;//这里sc->swappiness以服务器默认值60,distress默认值为(100>>ZONE_RECLAIM_PRIORITY)=(100>>4)=6。sc->swappiness取默认变量vm_swappiness = 60;当已经分配的内存占用了系统整体虚拟内存的(100-6-60)*2=68%之后,就可以启用将一些LRU不常用的页面移除到swap上。这个是大致值,这个分析不一定准确

/*
* Now use this metric to decide whether to start moving mapped
* memory onto the inactive list.
*/
if (swap_tendency >= 100)
force_reclaim_mapped:
reclaim_mapped = 1;
}
四、换出页面的实现及管理
linux-2.6.21\mm\swap_state.c
为了将没有文件backup的内存页面转换为文件写回操作,内核为所有这种页面创建一个伪文件,它有自己的address_space swapper_space 和address_space_operations swap_aops 。在shrink_page_list函数中,通过下面代码将页面添加到swap空间中
#ifdef CONFIG_SWAP
/*
* Anonymous process memory has backing store?
* Try to allocate it some swap space here.
*/
if (PageAnon(page) && !PageSwapCache(page))
if (!add_to_swap(page, GFP_ATOMIC))
goto activate_locked;
#endif /* CONFIG_SWAP */
下面是这个全局的swap的虚拟address_space结构(其实内核中共享内存shmem.c的实现也有自己的address_space_operations shmem_aops结构):
/*
 * swapper_space is a fiction, retained to simplify the path through
 * vmscan's shrink_list, to make sync_page look nicer, and to allow
 * future use of radix_tree tags in the swap cache.
 */
static const struct address_space_operations swap_aops = {
.writepage = swap_writepage,
.sync_page = block_sync_page,
.set_page_dirty = __set_page_dirty_nobuffers,
.migratepage = migrate_page,
};

static struct backing_dev_info swap_backing_dev_info = {
.capabilities = BDI_CAP_NO_ACCT_DIRTY | BDI_CAP_NO_WRITEBACK,
.unplug_io_fn = swap_unplug_io_fn,
};

struct address_space swapper_space = {
.page_tree = RADIX_TREE_INIT(GFP_ATOMIC|__GFP_NOWARN),
.tree_lock = __RW_LOCK_UNLOCKED(swapper_space.tree_lock),
.a_ops = &swap_aops,
.i_mmap_nonlinear = LIST_HEAD_INIT(swapper_space.i_mmap_nonlinear),
.backing_dev_info = &swap_backing_dev_info,
};

  评论这张
 
阅读(553)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017