欢迎来到课桌文档! | 帮助中心 课桌文档-建筑工程资料库
课桌文档
全部分类
  • 党建之窗>
  • 感悟体会>
  • 百家争鸣>
  • 教育整顿>
  • 文笔提升>
  • 热门分类>
  • 计划总结>
  • 致辞演讲>
  • 在线阅读>
  • ImageVerifierCode 换一换
    首页 课桌文档 > 资源分类 > DOCX文档下载  

    AIX 进程内存分配与回收策略及应用开发建议.docx

    • 资源ID:1163692       资源大小:191.27KB        全文页数:33页
    • 资源格式: DOCX        下载积分:5金币
    快捷下载 游客一键下载
    会员登录下载
    三方登录下载: 微信开放平台登录 QQ登录  
    下载资源需要5金币
    邮箱/手机:
    温馨提示:
    用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)
    支付方式: 支付宝    微信支付   
    验证码:   换一换

    加入VIP免费专享
     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    AIX 进程内存分配与回收策略及应用开发建议.docx

    目录1.AlX内存分配回收策略1.1 内存分配观察示例一递增分配1.2 内存分配观察示例一递减分配1.3 针对长逐行程序的空闲内存回收1.4 mallopt示例11.5 mallopt示例21.6 内存回收disclaim策略1.7 disclaimdisclaim64代码示例1.8 内存碎片对内存回收的影响1.9 通用建议2 .内存监控2.1 观察系统中内存占用最高的进程2.2 寻找内存持续增长的进程2.3 如何通过共享内存ID对应关联到该共享内存的进程2.4 如何获取AIXKernel的内存使用率2.5 如何判断系统是否存在内存不足3 .应用开发工具3. Idbx使用以及coredump定位3.2 内存非法使用检查3.3 内存泄漏检查(report_allocations)3.4 内存泄漏检查示例3.5 proctools介绍3.6 probevue介绍如何将C文件与汇编文件对应1.AlX内存分配回收策略一般而言,系统会直接在进程空间的free列表中维护其free释放的内存,以供后续新的分配直接使用,这样可以提高分配效率,不需要每次内存分配都经过系统内核。进程退出后,系统会回收该进程占用的全部内存。注:选择不同的分配策略时,对空闲内存空间的管理策略会有所差异。例如默认的管理结构是CarteSian树;而采用WatSon分配算法时,使用的管理结构是红黑树。Cartesian笛卡尔树参考结构:DeaeasrglengthsROOTInereaSngaddresses1.1 内存分配观察示例一递增分配进程的详细内存分配情况可以使用SVmon来观察,参考如下示例。需要注意,为方便svmon观察,示例代码需要在malloc之后调用memset进行初始化;因为操作系统实际上并不会立即对已申请但尚未访问到的内容分配实际存储空间,而是推迟到第一次访问时才会实际分配一这即是缺页机制的工作原理。如下是一个申请空间递增的应用,分配/释放大小为2MB->4MB->8MB->16MB,则通过各阶段的svmon可以看到,内存页面会持续增长,从2MB一直增力口到16MB(注意不是2MB+4MB+.+16MB=30MB)oManOC分配2MB,未初始化时:rtanzga:/#svmon-11rP909436PidCommandInusePinPgspVirtual64-bitMthrd16MB909436testm165848841727YNNVsidEsidTypeDescriptionPSizeInusePinPgspVirtual2cba711worktextdataBSSheaps2002AddrRange:0.512839b2ffffffffworkapplicationstacks2002AddrRange:65534.65535AddressRange为0512页,即代表512×4096=2MB虚拟地址空间。VirtUaI取值为2,表示该空间尚未实际分配。初始化后:2cba711worktextdataBSSheaps51300513AddrRange:0.512VimIaI取值为513,表明虚存空间已经实际分配。释放之前申请的2MB,重新申请4MB并初始化后:2cba711worktextdataBSSheaps1025001025AddrRange:0.10241024×4096=4MB,此前释放的512页虚拟地址空间被重复利用。释放之前申请的4MB,重新申请88MB并初始化后:2cba711worktextdataBSSheaps2049002049AddrRange:0.2048此前释放的1024页虚拟地址空间被重复利用。释放之前申请的8MB,重新申请16MB并初始化后:2cba711worktextdataBSSheaps4097004097AddrRange:0.40961.2 内存分配观察示例一递减分配如示例,如果是一个申请空间递减的应用,分配/释放大小为16MB->8MB->4MB->2MB,通过各阶段的svmon(svmon-nrP<pid>)可以看到,内存页面始终维持在16MBoMaIk)C分配16MB,未初始化时:VsidEsidTypeDescriptionPSizeInusePinPgspVirtualbl41411worktextdataBSSheaps2002ddrRange:0.40962cba7ffffffffworkapplicationstackAddressRange为04096页,即代表4096X4096=16MB虚拟地址空间。InuseZVirtual取值为2,表示该空间尚未实际分配。初始化后:VsidEsidTypeDescriptionPSizeInusePinPgspVirtualb!41411worktextdataBSSheaps4097004097AddrRange:0.4096Virtual=4097页,虚拟内存已经实际分配。释放之前申请的16MB,重新申请88MB并初始化后:b!41411worktextdataBSSheaps4097004097AddrRange:0.4096释放之前申请的8MB,重新申请44MB并初始化后:bl41411worktextdataBSSheaps4097004097AddrRange:0.4096释放之前申请的4MB,重新申请22MB并初始化后:bl41411worktextdataBSSheaps4097004097AddrRange:0.4096可以看到SVmOn输出结果没有变化;原因是虽然应用调用了free释放了16MB内存,但系统的处理策略是将该内存置于进程自身的空间块树中管理。下一个8MB分配,实际上是直接从进程已有的16MB空闲块中获取的。但对系统而言,进程管理的空闲块树也对应为该进程的内存消耗,所以其内存占用没有变化。测试代码:#include<stdio.h>include<stdlib.h>!include<errno.h>intmain(intargc,char*argv)(char*p;intsize=1024*4096;intindicator;if(argc"2)size=atoi(argv(l)*4096;p=(char*)malloc(size);printf("sizeofmalloc=%dMB,pressenternn,size/(1024*1024);getchar();memset(pr0rsize);getcharO;while(p!=NULL)(free(p);size=2;/如果用递增,则size*=2;p"(char*)malloc(size);memset(p,0zsize);if(p=NULL)(printf(nerrorencountered,mallocreturnNULL,error三%dn,errno);else(printf("sizeofmalloc三dMB,pressentern'size/(1024*1024);)getchar();1getchar();return0;1.3 针对长运行程序的空闲内存回收由于上面介绍的内存使用方式,一个常见的现象是,对于长运行进程,其占用的私有内存大小等同于最高峰时间的内存大小。这个现象一般而言,对系统正常运行及性能的影响很小。因为如果系统空闲内存足够,这个问题不存在。而如果内存不足,由于进程本身的空闲块列表没有被引用,根据换页算法,在系统缺页(即可用内存不足)时,很容易被换出。但如果应用进程希望对其空间内存块进行更自主的管理,可以使用mallopt接口。例如,对长运行的程序,定期在其闲时(例如每周日凌晨业务量极低时),调用mallopt(M_DISCLAIM,0)释放进程私有空间的free列表。这样可以避免在程序本身没有内存泄漏的情况下,因业务高峰期大量的内存申请造成的进程私有freelist增长,而使得进程内存占用过大。实现起来也相当简单(参考如下mallopt示例)。参考mallopt函数的帮助信息:CommandValueEffectM_D1SCLAIM0IfcalledwhiletheDefaultAllocatorisenabled,allfreememoryintheprocessheapisdisclaimed.1.4 mallopt示例1bladelrt:tmpcattestm.cpp#include<stdio.h>#include<sysshm.h>#include<stdlib.h>#include<malloc.h>ttinclude<errno.h>intmain(intargc,char*argv)char*p;intsize=8*1024*4096:p=(Char*)maIloc(size):mcmset(p,0,size);while(p!=NULL)(free(p);size=2;p=(char*)malIoc(size):memset(p,0,size);if(p=NULL)(printf(*errorencountered,mallocreturnNULL,error=%dn*,errno);else(printf(*sizeofmalloc=%dMBn*,size/(1024*1024);printf(*disclaim?YNn*);if(,Y*=getchar()mallopt(M_DISCLAIM,0);调用一次即可释放进程此前的私有freelistgetchar();)getchar();return0;)1.5 mallopt示例2AnothermalIoptexample:#include<iostream>#include<time.h>Itinclude<malloc.h>#include<stdlib.h>usingnamespacestd;voidmain()(cout«*Beginningprogram.Entertocontinue*«endl;constlongSizeOfArray=4*1024;chari:/pausebeforeallocatingcout«*wait*;getchar():cout«clock()/CLOCKS_PER_SEC«endl;char*pCsiZeOfArray:for(intj=0;j<sizefArray;j+)pCj=newchar4096;memset(pCj,0,4096):/pausebeforede-allocatingcout«*doneallocating16MB,pressentern*:getchar():for(intj=j<sizefArrayij+)deletepCj;cout«”donedeleting16MB,pressentern*;getcharO;cout«clock()/CLOCKSPERSEC«endl;/ReturnthememorytosystemmalIopt(M_DISCLAIM,NULL);/pauseafterde-allocatingcout«”donedeallocatingmemoryn”;getchar();)1.6 内存回收disclaim策略如果需要设置使得系统在应用调用free之后,即回收其内存,可以在程序启动前设置环境变量(这两种方式都可能对程序性能有很大影响):PSALLOC=early或者MALLOCOPTIONS=disclaim由于PSALLOC=early实际上意味着设置MALLOCOPTIONS=disclaim,且提前分配PagingSpace;所以其性能开销还要高于MALLOCOPTIONS=disclaimo但这种机制能够避免PagingSpace耗尽时,进程被系统kill掉的可能;详情可以通过在如下aixinfocenter网站查询PSALLOC获取。注:老的MALLOCTYPE=3.1也有此效果,但该分配策略往往性能一般,且只适用于32位程序,现在的系统一般不使用了。在设置环境变量MALLOCTYPE=Watson的情况下,mallopt(M_DISCLAIM,0)无效;1疝0向乂_口£(21,0)只对系统默认的分配策略(即cartesian树分配算法)有效。也可以在代码中直接用disclaim调用。注意disclaim调用需要在free/delete之前;超过4G的内存块需要使用disclaim64函数。1.7 disclaimdisclaim64代码示例blade1:root:/trapcattestm.cpp#include<stdio.h>#include<sysshm.h>*include<stdlib.h>#include<errno.h>intmain(intargc,char*argv)(char*p:intsize=10000000;p三(Char*)ma1Ioc(size);InemSeI(p,0,size):while(p!=NULL)(discIaim(char*)p.size,ZERO_MEM);/disclaimshouldcomesbeforefreesubroutine/forsize>=4G,disclaim64shouldbeused.free(p):size=2;p=(char*)malIoc(size):memset(p,0,size);/shouldraemsetforthepagestobeactuallyallocated.if(pNULL)printf(*errorencountered,malIocreturnNULL,error=%dn*,crrno);)else(printf(*sizeofmalIoc=%dMBn*,size/(1024*1024):getchar():getchar();return0;1.8 内存碎片对内存回收的影响需要注意的是,上面各种释放进程私有空闲内存列表的方法,在应用出现严重内存碎片的情况下,都存在不足。这种情况需要实际应用程序通过合理设计,避免严重内存碎片。例如一些缓存数据库表的数据结构,可能涉及大量记录的增删,且一般不会一次性全部删除,类似这种情况可能最终造成严重内存碎片;从而使得进程私有空间无法有效回收,只能存在于进程自身的私有freelist中。举一个极端的例子,一个进程申请了4000页内存,但释放时,恰好在每个内存页上保留了一个16字节的数据结构(其他空间均释放)。这样进程的私有内存空间实际上无法进行收缩。因为maHopt(M_DISCLAIM,0)和disclaim等方法都需要以多个页面为单位进行实际回收。但如果应用设计良好,一般可以避免这类问题:例如一些事务性的应用,在事务处理开始时,大量申请内存;在处理结束后,就将这些内存释放。这种情况下,出现大量内存碎片的概率较低。1.9 通用建议一般对内存受限程序的建议是:a.尽量使用malloc而不是callocob.提高引用局部性,即仅在数据结构马上要被使用前,对其进行初始化。c.对大的数据结构,如果使用一次后,后续不再使用,建议调用disclaim回收其分配的内存。参考:性能管理和调整>性能管理>性能规划和实现>有效的程序设计和实现>内存限制程序:要将数据工作集减至最小,请尝试集中常用数据以及避免对虚拟存储器页面不必要的引用。特别是:i .用malloc()或CalloC()子例程来仅请求实际需要的空间大小。当实际情况只使用数组的一小部分时,切勿请求然后初始化最大的数组。当您得到一个新页面用来初始化数组元素时,您实际上是强制VMM从别处窃取一个实内存页面。随后,当拥有该页面的进程尝试再次访问它时,会造成缺页故障°ma11oc()和calloc()子例程的差异不仅仅在接口上。ii .因为CalIoC()子例程将分配的存储器置零,它与每一个分配的页面相关,而malloc()子例程只与第一个页面相关。如果您用CalIOe()子例程分配一大块区域,然后最初只使用一小部分,那么您对系统施加了不必要的负载。不仅这些页面必须初始化;而且如果它们的实内存页面被系统回收(因为系统调页),那么已初始化但从未使用的页面必须写出到调页空间。这种情况浪费I/O和调页空间。iii .大结构(如缓冲区)的链表可以引起类似的问题。如果您的程序执行大量寻找某个特定关键字的链式跟踪,请考虑保持链接指针和关键字与数据分离或使用散列表方法来代替。iv .引用局部性也意味着时间上的局部性,而不仅仅是地址空间上。仅在使用之前初始化数据结构(如果使用的话)。在重负载系统中,在初始化和使用之间长时间驻留的数据结构有帧被窃取(因为系统调页)的危险。然后您的程序就会在开始使用数据结构时发生不必要的缺页故障。V.同样,如果早先使用一个大结构,然后与程序剩余部分无关联,它应该被释放。使用free。子例程来释放由malloc()或CaIlOe()子例程分配的空间是不够的。free()子例程仅仅释放结构占用的地址范围。要释放实内存和调页空间,也可使用disclaim。子例程来放弃空间。对disclaim。的调用应该在调用free。之前进行。2.内存监控2.1 观察系统中内存占用最高的进程后台运行3个nmem64进程:./nmem64-m2048-s3000-z80&按进程使用的虚拟内存进行排序,显示占用最高的前三项:#svmon-P-t3-OSegmCnt=Oflf-OSortentity=Virtual-Otimcstamp=onUnit:pageTimestamp:06:11:05PidCommandInusePinPgSPVirtual6094858nmem643350661099203350434194650nmem643102531099203102303604980nmcm64282245109920282222显示虚拟内存占用最高的3个进程的详细的内存段分布信息,如下:可以看到,消耗最多虚拟内存的段都是nmem64进程的数据段。#svmon-P-t3-Osegment=on-OSOrtentity=Virtual-Otimestamp=onUnit:pageTimestamp:06:10:57PidCommandInuscPin6094858nmem6427156110992PgspVirtual0271538VsidEsidTypeDescriptionPSizcInuscPinPgspVirtualc915c912worktextdataBSSheapsm655360065536ba163a13WoriCtextdataBSSheapsm655360065536890a8911worktextdataBSSheapsm655360065536c9164914worktextdataBSSheapsm582760058276200020workkernelsegmentm74668407469d00ld90000000worksharedlibrarytextm13900139500059flffldworksharedlibrarysm21730021739R)01f90020014worksharedlibraryS19700197acl42cfD(MXXXX)2workprocessprivatem53058616069001OOOaworksharedlibrarydatasm2000209ffflfflTclntUSLAtcxtdcvhd2r8!93S150-dOOOd9ffiT11cworksharedlibrarysm120012fl1167f10clnttextdataBSSheap,S80-cfl44fdevhdl:1229980020014workUSLAheapsm5005fc06fc8ff11HfworkprivateloaddataS5005871687fBTfilTworkapplicationstacksm1001cc15cc19worktextdataBSSheapsm1001c70bc7flfR11aworkapplicationstacksm0000ft147cfflfRT3workapplicationstackSm0000c6)6c6fTffffT2workapplicationstacksm0000cc!5ecf11Y11T5workapplicationstacksm0000cO15cOflT11TMworkapplicationstacksm0000bei5beworkapplicationstacksm00008c0d8cATffflbworkapplicationstackSm000011I6flffffffRworkapplicationstacksm0000cb15cbT11TI'1workapplicationslacksm0000a715a716worktextdataBSSheapsm00009al71a17worktextdataBSSheapSm0000961716fflTf11Dworkapplicationstacksm00008a160affftffifeworkapplicationstacksm0000e5l5e5ffRfflfcworkapplicationstackSm0000e7166715worktextdataBSSheapsm00000167218worktextdataBSSheapsm0000(415Mfl,11116workapplicationstacksm0000841704ffl-11B(lworkapplicationstacksm0000821702flllT117workapplicationstacksm0000PidCommandInusePin4194650nmem6424693310992VsidEsidTypeDescriptionPgspVirtual0246910PSizcInuscPinPgspVirtualfcl5fc13worktextdataBSSheapsm655360065536adl62d12worktextdataBSSheapsm655360065536cbl64bIlworktextdataBSSheapsm655360065536f915f914worktextdataBSSheapsm336480033648200020workkernelsegmentr174668407469d00ld90000000worksharedlibrarytextm139001395059f11lYfijworksharedlibrarj,sm21730021739fD01f900200)4worksharedlibraryS19700197ad16adf00000002workprocessprivatem5305d21652OOOBdOOOdffl67fb216329001000aworksharedlibrarydata9ffl11lTclntUSLAtcxtdevhd2r81939fflffifeworksharedlibrary10clnttextdataBSSheap,devhd1:1229980020014workUSLAheapsmSsmS200020120015128sr000n05d814d88ffflTfifworkprivateloaddataS5005cc164cHTnnFworkapplicationstackSm1001a9142919worktextdataBSSheapsm1001f916f918worktextdataBSSheapSm0000fa167affiT11T4workapplicationstacksm0000cal6caflf11fficworkapplicationstacksm0000e21662ffT11TPworkapplicationstackSm0000c416c4workapplicationstacksm0000ba15baftT1111cworkapplicationstackSm0000e5166515worktextdataBSSheapsm0000b115blfi11TfFlworkapplicationstackSm0000daI6dafff1111bworkapplicationstacksm0000b316b3flffil11)workapplicationstacksm0000cb!6cb17worktextdataBSSheapSm0000d215d2flffiTF7workapplicationstacksm0000a716a7f111111bworkapplicationstacksm000093159316worktextdataBSSheapSm000095171511T11113workapplicationstackSm00008H68fflTfffiaworkapplicationstackSm0000c6166611YT11K1workapplicationstacksm00008al68afflTfff5workapplicationstacksm0000ea15cafffflTfBworkapplicationstacksm0000PidCommandInuscPin3604980nmem6421951010992PgspVirtual0219487VsidEsidTypeDescriptionPSizcInuscPinPgspVirtual93171312worktextdataBSSheapsm65536006553693141313worktextdataBSSheapsm655360065536b7163711worktextdataBSSheapsm655360065536200020workkernelsegmentm746684074682160214worktextdataBSSheapSm62250062259d001d90000000worksharedlibrarytextm13900139500059flYF11(iworksharedlibrarySm21730021739fD01f90020014worksharedlibraryS19700197bl16bltD0000002workprocessprivatem5305ell6el9001000aworksharedlibrarydatasm2000209fflT11TclntUSLAtcxtdcvhd28193S150-dd9fftffifeworksharedlibrarysm120012AFl67f10clnttextdataBSShe叩,S80-dcvhdl:12299c014608f11T11TworkprivateloaddataS50058cl70c80020014workUSLAheapSm5009al69affT1111TworkapplicationstackSm1001cd15cd19worktextdataBSSheapsmI00Ic716c7ffflffl7workapplicationstacksm0000d314d3fffTffl4workapplicationstackSm0000ba16baftlT1111workapplicationstackSm0000d615d6ff11f113workapplicationstacksm0000820e0218worktextdataBSSheapsm0000cf!5cfff11T11aworkapplicationstackSm0000b016b0ff11T11bworkapplicationstacksm0000a0162015worktextdataBSSheapsm0000e015e0workapplicationstacksm0000c116cff1111YTOworkapplicationstackSm000093161316worktextdataBSSheapSm0000931693fiT11TRiworkapplicationstacksm000094171417worktextdataBSSheapsm0000cdl6cdf111111cworkapplicationstacksm0000c315c3f111111bworkapplicationstackSm0000ba143afiffl11cworkapplicationstacksm0000c215c2workapplicationstacksm0000871707fTffffl2workapplicationstacksm0000ddl45dworkapplicationstacksm00002.2 寻找内存持续增长的进程可以使用PSVg记录当前系统中各进程的内存消耗情况,然后通过比较多次PSVg的结果来判断是否存在一些进程有持续的内存增长。说明:进程存在持续内存增长并不一定意味着出现了内存泄漏。由于AIX内存分配采用了访问时分配的策略,进程申请大量内存时系统并不会第一时间分配内存,而是在进程使用过程中实际访问时才进行分配。由于这种分配策略,进程在启动初期可能存在内存持续增长的可能(例如数据库缓存需要一定时间才能完全填充);但其增长曲线应该是收敛到具体值的。#sh./postvg.shpsvg.befbrcpsvg.afterpidBeforeSizeAfterSizeDelta24252764484480255619275275206422598676260824096147836O5898292631312779288147976©3932188722668870840148172# ps -efegrep m642259858982923932 I 88h root 3932188 4587888 113 06:26:18root 5636326 66847120 06:27:20root 5898292 4587888 112 06:26:20root 6422598 4587888 112 06:26:19

    注意事项

    本文(AIX 进程内存分配与回收策略及应用开发建议.docx)为本站会员(夺命阿水)主动上传,课桌文档仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知课桌文档(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    备案号:宁ICP备20000045号-1

    经营许可证:宁B2-20210002

    宁公网安备 64010402000986号

    课桌文档
    收起
    展开