最近有同事在读<>一文,我也看了下,写得不错,满通俗易懂的,但是其中关于

进程mem map 显示的东西,好象没提供,我搜了下只找到个显示全部mem map 的,于是自己写了一个,

虽然代码很小,但写+调试也花了半天时间,废话少说 ,具体代码如下:

mem_map.c :

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define liuprintk printk

unsigned short *proc_memmap;

int msize;

struct page *vm_get_page(struct vm_area_struct *vma, unsigned long addr, pte_t pte)

{

unsigned long pfn = pte_pfn(pte);

if (unlikely(vma->vm_flags & (VM_PFNMAP|VM_MIXEDMAP))) {

liuprintk("\nliutest: has pure pfn \n");

#if 0

if (vma->vm_flags & VM_MIXEDMAP) {

if (!pfn_valid(pfn))

return NULL; /* invalid page */

goto out;

} else {

unsigned long off;

off = (addr - vma->vm_start) >> PAGE_SHIFT; /* VM_PFNMAP 的处理*/

if (pfn == vma->vm_pgoff + off)

return NULL;

if (!is_cow_mapping(vma->vm_flags))

return NULL;

}

#endif

}

//out:

return pfn_to_page(pfn);

}

static inline void

show_one_pte(struct mm_struct *mm, pte_t *src_pte, struct vm_area_struct *vma,

unsigned long addr) /* liunote linux pte */

{

unsigned long vm_flags = vma->vm_flags;

pte_t pte = *src_pte; /* get pte val */

struct page *page;

int pm_index;

if (unlikely(!pte_present(pte))) {

if (!pte_file(pte)) { /* liunote anymous page */

/* liunote can do it best */

}

goto out_show_pte;

}

page = vm_get_page(vma, addr, pte); /* 是normal page */

if (page) {

/* liunote get share proc num */

pm_index = (addr - vma->vm_start) /PAGE_SIZE;

proc_memmap[pm_index] = atomic_read(&(page)->_mapcount);

//printk("liutest pmd_index=0x%X,addr= 0x%X,vmstart=0x%X:,mapcount=%d", pm_index ,addr , vma->vm_start,atomic_read(&(page)->_mapcount));

if (proc_memmap[pm_index]==0){

proc_memmap[pm_index] =1;

}

}

out_show_pte:

return;

}

static int show_ptes(struct mm_struct *mm, pmd_t *pmd, struct vm_area_struct *vma,

unsigned long addr, unsigned long end)

{

pte_t *pte;

spinlock_t *ptl;

/* liunote below dst_pte is linux pte ??? */

pte = pte_offset_map_nested(pmd, addr);

ptl = pte_lockptr(mm, pmd);

/* liunote need lock to read it ??? */

/* spin_lock_nested(ptl, SINGLE_DEPTH_NESTING);*/

do {

if (pte_none(*pte)) { /* src_pte = 0 */

//liuprintk("\nliutest: bad pte=0x%X,addr=0x%X\n",pte,addr);

continue;

}

show_one_pte(mm, pte, vma, addr);

} while (pte++, addr += PAGE_SIZE, addr != end);

/* spin_unlock(ptl); */

return 0;

}

static inline int show_pmds(struct mm_struct *mm, pud_t *pud, struct vm_area_struct *vma,

unsigned long addr, unsigned long end)

{

pmd_t * pmd;

unsigned long next;

pmd = pmd_offset(pud, addr);

do {

next = pmd_addr_end(addr, end);

if (pmd_none_or_clear_bad(pmd)){

liuprintk("\nliutest: bad pmd=0x%X,addr=0x%X\n",pmd,addr);

continue;

}

if (show_ptes(mm, pmd,

vma, addr, next))

return -ENOMEM;

} while (pmd++, addr = next, addr != end);

return 0;

}

static inline int show_puds(struct mm_struct *mm, pgd_t *pgd, struct vm_area_struct *vma,

unsigned long addr, unsigned long end)

{

pud_t *pud ;

unsigned long next;

pud = pud_offset(pgd, addr);

do {

next = pud_addr_end(addr, end);

if (pud_none_or_clear_bad(pud)){

liuprintk("\n liutest: bad pud=0x%X,addr=0x%X\n",pud,addr);

continue;

}

if (show_pmds(mm, pud,

vma, addr, next))

return -ENOMEM;

} while (pud++, addr = next, addr != end);

return 0;

}

// liuadd for print pte

int show_pages(struct mm_struct * mm, struct vm_area_struct *vma)

{

pgd_t *pgd;

unsigned long next;

unsigned long addr = vma->vm_start;

unsigned long end = vma->vm_end;

int ret,i;

int pages =0;

// according vm size ,malloc proc memmap

msize = end-addr;

msize = (msize & (PAGE_SIZE-1)) ? (msize+PAGE_SIZE)/PAGE_SIZE : msize/PAGE_SIZE;

liuprintk("\nliutest: msize =0x%X, PAGE_SIZE=0x%X\n",msize,PAGE_SIZE);

proc_memmap = kmalloc( msize*(sizeof(unsigned short)),GFP_KERNEL);

if(proc_memmap == NULL){

printk("\n liutest : proc mem map alloc fail \n");

return 1;

}

for(i=0; i

proc_memmap[i] = 0;

/*

if (!(vma->vm_flags & (VM_HUGETLB|VM_NONLINEAR|VM_PFNMAP|VM_INSERTPAGE))) {

if (!vma->anon_vma)

return 0;

}

*/

ret = 0;

pgd = pgd_offset(mm, addr);

do {

next = pgd_addr_end(addr, end);

if (pgd_none_or_clear_bad(pgd)){

liuprintk("\nliutest: bad pgd=0x%X,addr=0x%X\n",pgd,addr);

continue;

}

if (unlikely(show_puds(mm, pgd, vma, addr, next))) {

ret = -ENOMEM;

break;

}

} while (pgd++, addr = next, addr != end);

#if 1

for(i=0; i

if(proc_memmap[i])

pages++;

printk("\nliutest: this vm area has pages =0x%X\n",pages);

// free memmap

kfree(proc_memmap);

#endif

return ret;

}

#undef liuprintk

上面mem_map.c 文件加到proc 目录下

然后在task_mmu.c show_map_vma 函数末尾加上:

show_pages(vma->vm_mm, vma);

proc 下面Makefile 加上 mem_map.o

代码有点乱,不过测试过还行,内容全在proc_memmap 数组里,大小为msize,

可根据自己喜好显示从proc 输出

下面是测试busybox内存情况

Cd proc

Cd 1

Cat maps显示如下:

00008000-00100000 r-xp 00000000 00:01 60         /bin/busybox

Pages:0xF8-0x4D      ( F8页,实际占用4D页,下面是实际页内存引用情况)

0x0002 0x0002 0x0000 0x0000 0x0002 0x0002 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000

0x0000 0x0000 0x0000 0x0000 0x0000 0x0001 0x0001 0x0001 0x0001 0x0001 0x0001 0x0001 0x0001 0x0001 0x0001 0x0001 0x0001 0x0001 0x0001 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0001 0x0000 0x0001 0x0001 0x0000 0x0000 0x0000

0x0000 0x0000 0x0000 0x0000 0x0002 0x0000 0x0002 0x0000 0x0000 0x0002 0x0002 0x0002 0x0002 0x0000 0x0000 0x0000 0x0000 0x0001 0x0001 0x0001 0x0001 0x0000 0x0000 0x0000 0x0001 0x0001 0x0000 0x0000 0x0001 0x0001 0x0001 0x0001

0x0001 0x0001 0x0002 0x0002 0x0002 0x0002 0x0002 0x0001 0x0002 0x0002 0x0001 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0001 0x0002 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000

0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0001 0x0002 0x0000 0x0000 0x0002 0x0002 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0002 0x0002

0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0002 0x0001 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0001 0x0000 0x0000 0x0000 0x0002 0x0000 0x0000 0x0000 0x0000 0x0000

0x0000 0x0002 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0002 0x0001 0x0002 0x0000 0x0002 0x0000 0x0001 0x0001 0x0000 0x0000 0x0000

0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0001 0x0000 0x0000 0x0002 0x0002 0x0000 0x0002 0x0002 0x0000 0x0000 0x0002 0x0000 0x0001 0x0001 0x0001 0x0001 0x0000 0x0000

00107000-00108000 rw-p 000f7000 00:01 60         /bin/busybox

Pages:0x1-0x1

0x0001

00108000-0012e000 rw-p 00108000 00:00 0          [heap]

Pages:0x26-0x6

0x0001 0x0001 0x0000 0x0001 0x0001 0x0001 0x0001 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000

0x0000 0x0000 0x0000 0x0000 0x0000 0x0000

40000000-40001000 rw-p 40000000 00:00 0

Pages:0x1-0x1

0x0001

be844000-be859000 rw-p befeb000 00:00 0          [stack]

Pages:0x15-0x2     (这是栈,有15页,实际占用2页,下面也可以看出,占了倒数的两页符合栈特性,)

0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0000 0x0001 0x0001

linux进程map,linux内存优化一文中 查看进程mem_map 的实现相关推荐

  1. Linux上怎样停止服务(jar包)、查看进程路径、关闭指定端口

    场景 在linux上部署的jar包服务需要停止该服务并关闭防火墙对应的端口. 注: 博客: https://blog.csdn.net/badao_liumang_qizhi 关注公众号 霸道的程序猿 ...

  2. 【回眸】Linux内核(六)进程是什么?如何复刻查看进程号命令?

    前言 很快到了Linux内核的第二阶段,接下来的文章都是关于Linux内核里关于进程的一些编程 什么是程序,什么是进程,两者有什么区别 程序是静态概念,比如gcc编译后产生的./a.out文件 当程序 ...

  3. aix查看oracle进程内存使用情况,AIX 查看进程的内存使用情况

    svmon-P命令显示系统上当前正在运行的所有进程的内存使用情况统计信息. 下面是 svmon -P 命令的示例: # svmon -P ------------------------------- ...

  4. Linux系统性能分析:内存 优化

    整体的内存基本原理和内存性能指标.性能瓶颈分析以及优化思路可参考如下导图 原始xmind文件路径Mind-Mapping

  5. linux进程map,LInux环境运行mapReduce程序

    将工程整体打成一个jar包并上传到linux机器上, 准备好要处理的数据文件放到hdfs的指定目录中 用命令启动jar包中的Jobsubmitter,让它去提交jar包给yarn来运行其中的mapre ...

  6. linux查看主板最大内存容量,Linux下查看内存插槽数、最大...-linux下手动清理内存或缓存的...-查看linux主板内存槽与内存信息的方法详解_169IT.COM...

    一.先来看几个用dmidecode查看内存信息的例子. 1.查看内存槽数.那个槽位插了内存,大小是多少 代码示例: dmidecode|grep -P -A5 "Memory\s+Devic ...

  7. linux查看运行的程序c pu,在Linux系统中,采用()一命令查看进程输出的信息,得到下图所示的结果。系统启动时最先运行的进程是...

    Routing.protocols use different techniques for assigning[S1]to individual networks.Further,each rout ...

  8. Linux性能优化-内存优化

    目录 1.内存原理 1.1.内存映射 1.2.虚拟内存空间分布 1.3.SWAP运行原理 2.内存性能统计信息 2.1.内存系统使用量 2.2.缓存与缓冲区命中率 3.性能剖析 3.1.内存性能指标 ...

  9. linux进程中的内存分布

    很多小伙伴在调试C代码的时候非常痛苦,C语言不像java那样可以给你指出具体的错误地方和错误原因,C语音因为指针的特殊性和C语言版本的兼容性的需要,很难直接定位到错误的地方.特别是各种段错误.溢出等. ...

最新文章

  1. 领域驱动设计_软件核心复杂性应对之道
  2. Nmap/Netcat/Hping3工具对比
  3. spring基础系列--JavaConfig配置
  4. BZOJ[1051]受欢迎的牛
  5. Qt之可重入与线程安全
  6. (原創) 如何将字符串前后的空白去除? (使用string.find_first_not_of, string.find_last_not_of) (C/C++)...
  7. python tqdm自定义更新进度条
  8. 使用Ado.net Entity快速建立基于WCF的Winform Silverlight应用
  9. Oracle Database 11g Express Edition学习笔记
  10. python字符串替换
  11. python音频特征提取_音频特征提取——常用音频特征
  12. Android图片轮播控件
  13. 第一章 接口测试基础
  14. 类似微信群聊九宫格头像的算法实现
  15. 大数据职业理解_3大数据职业职位描述及其职业要求
  16. 完美解决matlab“错误使用 mex未找到支持的编译器或 SDK。”的问题
  17. deepFM model
  18. html5圣诞贺卡,用CorelDRAW制作漂亮别致的圣诞贺卡
  19. 通用计算机与嵌入式的比较,嵌入式系统与通用计算机系统相比有什么特点?如题 谢谢了...
  20. Selenium爬取MOOC网课程信息

热门文章

  1. win7移动设备管理器_win7系统usb设备识别不了的解决方案
  2. mt6761v/cbb处理器相当于骁龙多少?_三星S21骁龙版首个跑分成绩出炉 骁龙875或非正式名称...
  3. redis之django-redis
  4. 袁永福的博客系列文章链接集合
  5. Win10不能直接拖文件/Foxmail不能拖文件解决办法
  6. 机器学习sklearn
  7. ffmpeg 推流 在H264中插入SPS、PPS 头
  8. 简述mysql事件作用_MYSQL使用简述
  9. 浏览器获取CA认证流程
  10. adb devices报错:* daemon not running. starting it now on port 5037(端口未被占用)解决