我是靠谱客的博主 深情哈密瓜,最近开发中收集的这篇文章主要介绍从MAP_SHARED谈RSS与PSS,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

  近期遇到一个问题:统计一个进程使用的物理内存居然远远超过了系统总内存大小。咋一看这个现象被下了一跳,怎么会这样呢?后来慢慢分析,终于了解到其中的奥秘.....

  我的 "进程占用物理内存统计" 是通过累加 /proc/pid/smaps中的Rss项来计算的。以往对Rss"Resident Set Size"的理解就是实际占用的内存,但是并没有真正去区分和Pss的区别。

  随后我仔细观察,才发现这次出问题的这个进程的Pss和Rss是不一样的:Pss累计统计出来的内存量是比较合理的。这是怎么回事呢?

  网上又查找了一番Rss和Pss的区别,都谈到了Rss是包含了共享库而Pss则比例分配共享库占用的内存。带着这些信息线索我又分析了两个方面: 1) 出问题的进程是如何消耗/分配内存的 ; 2) 内核中究竟是如何统计Rss和Pss的。

  方向1

  代码中主要内存消耗的代码为:

mmap(NULL, LENTH, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);

即通过mmap()函数对一个文件进行LENTH大小的多次映射,并最终写这段映射出来的地址来消耗内存。

通过实验发现,如果mmap()函数不使用MAP_SHARED标志作为参数,则Rss统计值和Pss值一致,同时其Rss的统计值不会超过系统内存总量。

方向2

内核统计smaps中Rss和Pss的主要代码逻辑:
 

for 遍历进程的vma
通过vma中各个的页的虚拟地址分解为对应的页表项
smaps_pte_entry()-->
smaps_account(mss, page, PAGE_SIZE, pte_young(*pte), pte_dirty(*pte))

smaps_pte_entry()函数首先找到pte对应物理页框的page结构,然后调用smaps_account()函数将此page统计到Rss和Pss中。具体一个page的统计方式如下:

static void smaps_account(struct mem_size_stats *mss, struct page *page,
unsigned long size, bool young, bool dirty)
{
int mapcount;
if (PageAnon(page))
mss->anonymous += size;
mss->resident += size;
/* 将page size 统计到Rss */
/* Accumulate the size in pages that have been accessed. */
if (young || page_is_young(page) || PageReferenced(page))
mss->referenced += size;
mapcount = page_mapcount(page);
if (mapcount >= 2) {
u64 pss_delta;
if (dirty || PageDirty(page))
mss->shared_dirty += size;
else
mss->shared_clean += size;
pss_delta = (u64)size << PSS_SHIFT;
do_div(pss_delta, mapcount); /* 如果一个物理页映射多次则Pss均分 */
mss->pss += pss_delta;
} else {
if (dirty || PageDirty(page))
mss->private_dirty += size;
else
mss->private_clean += size;
mss->pss += (u64)size << PSS_SHIFT;
}
}

从上面代码可以看出:(1)只要进程虚拟地址映射到物理页就会统计到Rss中,不论这些物理页是否被多次映射; (2) Pss在统计进程虚拟地址空间每个映射的物理页时会div物理页映射的counts,即会均分多次映射的page。

而出问题的进程正好是以MAP_SHARED的方式多次映射同一个文件,这样多次映射的虚拟地址实际上只会对应到相同的物理页,因而也就有上述问题。

所以,以后再计算进程占用物理内存时,Rss和Pss如果不一样就需要考虑是否是有多次映射或者和共享映射的情况。

 

最后

以上就是深情哈密瓜为你收集整理的从MAP_SHARED谈RSS与PSS的全部内容,希望文章能够帮你解决从MAP_SHARED谈RSS与PSS所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(74)

评论列表共有 0 条评论

立即
投稿
返回
顶部