1、/proc/meminfo
memtotal:这个对应全局变量totalram_pages,系统出了内核代码段、数据段、memblock.reserved等的内存外一共系统可管理的内存,即可被伙伴系统管理的内存。
memfree:表示系统尚未使用的内存。[MemTotal-MemFree]就是已被用掉的内存.
memavailable:有些应用程序会根据系统的可用内存大小自动调整内存申请的多少,所以需要一个记录当前可用内存数量的统计值,MemFree并不适用,因为MemFree不能代表全部可用的内存,系统中有些内存虽然已被使用但是可以回收的,比如cache/buffer、slab都有一部分可以回收,所以这部分可回收的内存加上MemFree才是系统可用的内存,即MemAvailable。/proc/meminfo中的MemAvailable是内核使用特定的算法估算出来的,要注意这是一个估计值,并不精确.
2、slabinfo
void get_slabinfo(struct kmem_cache *cachep, struct slabinfo *sinfo)
{
struct page *page;
unsigned long active_objs;
unsigned long num_objs;
unsigned long active_slabs = 0;
unsigned long num_slabs, free_objects = 0, shared_avail = 0;
const char *name;
char *error = NULL;
int node;
struct kmem_cache_node *n;
active_objs = 0;
num_slabs = 0;
for_each_kmem_cache_node(cachep, node, n) {
check_irq_on();
spin_lock_irq(&n->list_lock);
list_for_each_entry(page, &n->slabs_full, lru) {
if (page->active != cachep->num && !error)
error = "slabs_full accounting error";
active_objs += cachep->num;
active_slabs++;
}
list_for_each_entry(page, &n->slabs_partial, lru) {
if (page->active == cachep->num && !error)
error = "slabs_partial accounting error";
if (!page->active && !error)
error = "slabs_partial accounting error";
active_objs += page->active;
active_slabs++;
}
list_for_each_entry(page, &n->slabs_free, lru) {
if (page->active && !error)
error = "slabs_free accounting error";
num_slabs++;
}
free_objects += n->free_objects;
if (n->shared)
shared_avail += n->shared->avail;
spin_unlock_irq(&n->list_lock);
}
num_slabs += active_slabs;
num_objs = num_slabs * cachep->num;
if (num_objs - active_objs != free_objects && !error)
error = "free_objects accounting error";
name = cachep->name;
if (error)
printk(KERN_ERR "slab: cache %s error: %s\n", name, error);
sinfo->active_objs = active_objs;//slab中已经分配出去激活状态的object
sinfo->num_objs = num_objs;//当前slab中所有的object个数
sinfo->active_slabs = active_slabs;//包含full和partial full,不包含free的slab个数
sinfo->num_slabs = num_slabs;//3表管理的所有slab个数
sinfo->shared_avail = shared_avail;
sinfo->limit = cachep->limit;//cpu高速缓存中空闲的最大数目
sinfo->batchcount = cachep->batchcount;//一次向cpu高速缓存中放入的batch
sinfo->shared = cachep->shared;
sinfo->objects_per_slab = cachep->num;//每个slab包含多少个obj
sinfo->cache_order = cachep->gfporder;//每个slab需要多少个页帧
}
这个是从3表管理结构中取出数据计算。首先说一下这里的page结构体指的是什么,指的是每个slab(2^n个页帧)第一个页帧的首地址,page->active这个slab已经分配出去的对象object。
再强调一下,slab包含2^n个页帧,每个slab包含很多个object对象,3表示将这些slab用链表串起来,同时也记录了object的数据,注意区分active_slab和active_objs。