文章归档

memory.usage_in_bytes内存只增不减

今天发现了一个问题,似乎memory.usage_in_bytes的内存总是在不停的增加,但很少减少,并不能说不减,只是很少。即使这个cgroup里的进程全kill了,usage_in_bytes依然纹丝不动。

经过分析之后,原因如下,与memory.usage_in_bytes的统计方式有关:

  1. 内核在统计的时候,usage_in_bytes包含进程的命名页 + 匿名页,匿名页通常就是file cache
  2. file cache是谁第一次使用算到谁的头上。
  3. file cache只有在完完全全被释放掉之后才会从usage_in_bytes中减掉,即使第一次使用它的进程早已死亡。

简单来说,就是我(某进程)读文件产生的file cache你(内核)算到我的头上,我退出了你也不清空我的计数,万一这个文件正好又被别的cgroup的进程依赖了,这笔帐还是赖在我的头上。。(内核虽然这么做,但其实是不合理的)

1、charge(计入)

file cache的charge函数是mem_cgroup_cache_charge(),这个函数通常是在文件页第一次被读上来时,内核将其加到file cache中时被调用,贴一个常见的调用栈:

  [<ffffffff8116019d>] ? mem_cgroup_cache_charge+0xed/0x130
  [<ffffffff8110bdba>] ? add_to_page_cache_locked+0xea/0x160
  [<ffffffff8119c232>] mpage_readpages+0x102/0x150
  [<ffffffff8120157d>] ext4_readpages+0x1d/0x20
  [<ffffffff8110c521>] do_generic_file_read.clone.23+0x271/0x450
  [<ffffffff8110d1ba>] generic_file_aio_read+0x1ca/0x240
  [<ffffffff81164c82>] do_sync_read+0xd2/0x110
  [<ffffffff81165463>] vfs_read+0xc3/0x180
  [<ffffffff81165571>] sys_read+0x51/0x90

page cache的维护是独立于进程的,所以即使cgroup里的进程退出后,其所使用的page cache不会马上被释放。

2、uncharge(计出)

file cache的计出函数是 mem_cgroup_uncharge_cache_page(),uncharge主要有三种情况:

  1. 手动触发内核回收file cache时被调用
  2. 文件被删除
  3. 内核主动回收file cache时被调用。

手动触发回收file cache,通过sysctl修改vm.drop_caches的值来实现,调用栈如下:

[<ffffffff81114bae>] __mem_cgroup_uncharge_common+0x1ab/0x1f6
[<ffffffff81114c09>] mem_cgroup_uncharge_cache_page+0x10/0x12
[<ffffffff810e0ad0>] __remove_mapping+0xd0/0xf4
[<ffffffff810e0b0a>] remove_mapping+0x16/0x2f
[<ffffffff810dfb75>] invalidate_inode_page+0x84/0x8d
[<ffffffff810dfc0c>] invalidate_mapping_pages+0x8e/0x114
[<ffffffff81138853>] drop_pagecache_sb+0x7f/0xd4
[<ffffffff811387d4>] ? drop_pagecache_sb+0x0/0xd4
[<ffffffff8111c253>] iterate_supers+0x77/0xc0
[<ffffffff811387ac>] drop_caches_sysctl_handler+0x30/0x58
[<ffffffff8116aa9c>] proc_sys_call_handler+0x90/0xb6
[<ffffffff8116aad6>] proc_sys_write+0x14/0x16
[<ffffffff8111ae72>] vfs_write+0xb0/0x10a
[<ffffffff8111af9a>] sys_write+0x4c/0x75

另一种情况就是内核主动回收file cache,通常就是内存资源紧张的时候进行。这个改天单独有空整理一下。

Leave a Reply

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>