Android内存等信息

1. Linux中proc目录下文件详解 http://wenku.baidu.com/view/2ce89f00a6c30c2259019ef1.html

2. Android系统/proc目录详解

3. android proc 进程信息解析 http://wenku.baidu.com/view/6530ad58312b3169a451a4eb.html?re=view

4. How to get memory usage at run time in c++?

5. 使用getrusage获取进程使用系统资源信息 http://www.cfanz.cn/index.php?c=article&a=read&id=69687

6. 获取CPU使用情况信息(转)

7. Android内存之VSS/RSS/PSS/USS     http://blog.csdn.net/hunanwy/article/details/8645335

VSS:Virtual Set Size,虚拟耗用内存。它是一个进程能访问的所有内存空间地址的大小。这个大小包含了
一些没有驻留在RAM中的内存,就像mallocs已经被分配,但还没有写入。VSS很少用来测量程序的实际使
用内存。

RSS:Resident Set Size,实际使用物理内存。RSS是一个进程在RAM中实际持有的内存大小。RSS可能会
产生误导,因为它包含了所有该进程使用的共享库所占用的内存,一个被加载到内存中的共享库可能有很
多进程会使用它。RSS不是单个进程使用内存量的精确表示。

PSS:Proportional Set Size,实际使用的物理内存,它与RSS不同,它会按比例分配共享库所占用的内存。
例如,如果有三个进程共享一个占30页内存控件的共享库,每个进程在计算PSS的时候,只会计算10页。
PSS是一个非常有用的数值,如果系统中所有的进程的PSS相加,所得和即为系统占用内存的总和。当一个
进程被杀死后,它所占用的共享库内存将会被其他仍然使用该共享库的进程所分担。在这种方式下,PSS
也会带来误导,因为当一个进程被杀后,PSS并不代表系统回收的内存大小。

USS:Unique Set Size,进程独自占用的物理内存。这部分内存完全是该进程独享的。USS是一个非常有用
的数值,因为它表明了运行一个特定进程所需的真正内存成本。当一个进程被杀死,USS就是所有系统回
收的内存。USS是用来检查进程中是否有内存泄露的最好选择。

 

> cat /proc/self/statm 
105 105 93 4 12 89 12 
.............................................................................. 
数据项 内容 
size 程序大小 
resident 常驻内存空间大小 
shared 共享内存页数 
trs 代码段占用内存页数 
drs 数据/堆栈段占用内存页数 
lrs 引用库占用内存页数 
dt 脏页数量 

 

方式一:

int ret = getrusage(RUSAGE_SELF, &ru);
    if(ret != -1)
        printf("ou/inblock:%ld,%ld,snd/rcvmsg:%ld,%ld,max/ix/idrss:%ld,%ld,%ld,min/majflt:%ld,%ld,signal:%ld,nv/nivcsw:%ld,%ld,swap:%ld,utime:%d,%lu,stime:%d,%lu\r\n", ru.ru_oublock, ru.ru_inblock, ru.ru_msgsnd, ru.ru_msgrcv, ru.ru_maxrss, ru.ru_ixrss, ru.ru_idrss, ru.ru_minflt, ru.ru_majflt, ru.ru_nsignals, ru.ru_nvcsw, ru.ru_nivcsw, ru.ru_nswap, ru.ru_utime.tv_usec, ru.ru_utime.tv_sec, ru.ru_stime.tv_usec, ru.ru_stime.tv_sec);
    char buff[512];
    sprintf(buff, "utime=%d, stime=%d, maxrss=%ld\n", ru.ru_utime, ru.ru_stime, ru.ru_maxrss);

 画线

void HelloWorld::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
{
    _customCommand.init(_globalZOrder);
    _customCommand.func = CC_CALLBACK_0(HelloWorld::onDraw, this, transform, flags);
    renderer->addCommand(&_customCommand);
}

void HelloWorld::onDraw(const cocos2d::Mat4 &transform, bool transformUpdated)
{
    //利用Stack缓存
    Director *director = Director::getInstance();
    //CCASSERT(nullptr != director, "Director is null when setting matrix stack");
    director->pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
    director->loadMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW, transform);
    
    CHECK_GL_ERROR_DEBUG();
    
    //画边框
    DrawPrimitives::setDrawColor4B(255, 0, 0, 255);//设置颜色
    glLineWidth(5);
    Vec2 vertices[] = {Vec2(100, 100), Vec2(200, 200), Vec2(300, 100), Vec2(400, 300)};
    DrawPrimitives::drawPoly(vertices, 4, false);
    
    CHECK_GL_ERROR_DEBUG();
    
    //绘制停止,释放
    director->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
}

 

linux下/proc/stat 计算CPU利用率

http://www.linuxdiyf.com/viewarticle.php?id=109486

http://blog.csdn.net/lanmanck/article/details/5989197

 

Process Memory

You can see an individual process' memory usage by examining /proc/<pid>/status

Details about memory usage are in

  • /proc/<pid>/statm
  • /proc/<pid>/maps
  • /proc/<pid>/smaps

The 'top' command will show VSS and RSS.

Commands for run time memory usage

  • To spit out a bunch of information about the memory use of each JAVA process
$adb shell dumpsys meminfo 
  • To see memory for particular process: ( e.g. System)
$adb shell dumpsys meminfo system
  • Summary of the overall memory
$adb shell cat /proc/meminfo 

Android Memory Management: Understanding App PSS

http://www.littleeye.co/blog/2013/06/11/android-memory-management-understanding-app-pss/

 

非常有用:

http://hubingforever.blog.163.com/blog/static/17104057920114411313717/

 

Android中如何查看内存(上)

 

Memory profiler Design

1. collect memory allocation information

2. related the collected information with the program structure

3. statistic analysis

4. present the result.

 

内存碎片之如何产生

 

内存分配的原理__Linux虚拟内存管理(glibc)_Linux的虚拟内存管理有几个关键概念_Linux 虚拟地址空间如何分布_malloc和free是如何分配和释放内存_如何查看堆内内存的碎片情况_既然堆内内存brk和sbrk不能直接释放,为什么不全部使用 mmap 来分配,munmap直接释放呢  

http://blog.163.com/xychenbaihu@yeah/blog/static/132229655201311884819764/

如果想知道堆内究竟有多少碎片,可通过 mallinfo 结构中的 fsmblks 、smblks 、ordblks 值得到,这些值表示不同大小区间的碎片总个数,这些区间分别是 0~80 字节,80~512 字节,512~128k 。如果 fsmblks 、 smblks 的值过大,那碎片问题可能比较严重了。 
    不过, mallinfo 结构有一个很致命的问题,就是其成员定义全部都是 int ,在 64 位环境中,其结构中的 uordblks/fordblks/arena/usmblks 很容易就会导致溢出,应该是历史遗留问题,使用时要注意!

分配内存时如何减少内存碎片

感觉面试的时候经常会被问到这个问题,然后我也学习了一下Memcached的slab机制,发现很多服务器都是使用这种机制来分配内存,所以决定学习一下。

  首先,先对内存分配中的伙伴系统有初步的了解:

  在编程和使用的服务器软件中,经常需要分配一组连续的页框,而频繁地申请和释放不同大小的连续页框,必然导致在已分配页框的内存块中分散了许多小块的空闲页框。这样,即使这些页框是空闲的,但要分配一个大块的连续页框就可能无法满足。

  而Linux采用了伙伴系统来解决上述难题。把所有的空闲页框分组为11个块链表,每个块链表分别包含大小为1,2,4,8,16,32,64,128,256,512和1024个连续页框的页框块。最大可以申请1024个连续页框,对应4MB大小的连续内存。每个页框块的第一个页框的物理地址是该块大小的整数倍。例如,大小为16个页框的块,其起始地址是16×212的倍数。

  假设要申请一个256个页框的块,先从256个页框的链表中查找空闲块,如果没有,就去512个页框的链表中找,找到了则将页框块分为2个256个页框的块,一个分配给应用,另外一个移到256个页框的链表中。如果512个页框的链表中仍没有空闲块,继续向1024个页框的链表查找,如果仍然没有,则返回错误。

  页框块在释放时,内核会主动将两个互为伙伴的页框块合并为一个较大的页框块,成功后会试图寻找伙伴并合并为更大的内存块,直至块的大小超过上限或者没有伙伴为止。互为伙伴的两个内存块必须符合以下条件:

  1、两个块具有相同的大小;
  2、第一个快的物理地址是两个块大小的整数倍。
  3、两个块的物理地址连续;

  slab分配机制则是对伙伴算法的改进,slab(Slab Allocation)的设计理念是基于对象缓冲的,基本想法是避免重复大量的初始化和清理操作。slab主要可以用于频繁非配释放的内存对象。替代malloc/free

  改进的地方在于:

  它对内存区的处理并不需要进行初始化或回收。出于效率的考虑,Linux并不调用对象的构造或析构函数,而是把指向这两个函数的指针都置为空。Linux中引入Slab的主要目的是为了减少对伙伴算法的调用次数。

  实际上,内核经常反复使用某一内存区。例如,只要内核创建一个新的进程,就要为该进程相关的数据结构(task_struct、打开文件对象等)分配内存区。当进程结束时,收回这些内存区。因为进程的创建和撤销非常频繁,因此,Linux的早期版本把大量的时间花费在反复分配或回收这些内存区上。从Linux2.2开始,把那些频繁使用的页面保存在高速缓存中并重新使用。 可以根据对内存区的使用频率来对它分类。对于预期频繁使用的内存区,可以创建一组特定大小的专用缓冲区进行处理,以避免内碎片的产生。对于较少使用的内存区,可以创建一组通用缓冲区(如Linux2.0中所使用的2的幂次方)来处理,即使这种处理模式产生碎片,也对整个系统的性能影响不大。

  硬件高速缓存的使用,又为尽量减少对伙伴算法的调用提供了另一个理由,因为对伙伴算法的每次调用都会“弄脏”硬件高速缓存,因此,这就增加了对内存的平均访问次数。

  Slab分配模式把对象分组放进缓冲区

  对于小对象, 就把Slab的描述结构slab_t放在该Slab中;对于大对象,则把Slab结构游离出来,集中存放。关于Slab中的着色区再给予具体描述:

  每个Slab的首部都有一个小小的区域是不用的,称为“着色区(coloring area)”。着色区的大小使Slab中的每个对象的起始地址都按高速缓存中的”缓存行(cache line)”大小进行对齐(80386的一级高速缓存行大小为16字节,Pentium为32字节)。因为Slab是由1个页面或多个页面(最多为32)组成,因此,每个Slab都是从一个页面边界开始的,它自然按高速缓存的缓冲行对齐。但是,Slab中的对象大小不确定,设置着色区的目的就是将Slab中第一个对象的起始地址往后推到与缓冲行对齐的位置。因为一个缓冲区中有多个Slab,因此,应该把每个缓冲区中的各个Slab着色区的大小尽量安排成不同的大小,这样可以使得在不同的Slab中,处于同一相对位置的对象,让它们在高速缓存中的起始地址相互错开,这样就可以改善高速缓存的存取效率。

  每个Slab上最后一个对象以后也有个小小的废料区是不用的,这是对着色区大小的补偿,其大小取决于着色区的大小,以及Slab与其每个对象的相对大小。但该区域与着色区的总和对于同一种对象的各个Slab是个常数。

  每个对象的大小基本上是所需数据结构的大小。只有当数据结构的大小不与高速缓存中的缓冲行对齐时,才增加若干字节使其对齐。所以,一个Slab上的所有对象的起始地址都必然是按高速缓存中的缓冲行对齐的。

posted @ 2015-07-14 11:57  wiessharling  阅读(380)  评论(0编辑  收藏  举报