使用python动态控制linux系统的内存占用百分比.doc
如何使用PYTHON动态控制LINUX系统的内存占用百分比近期有网上朋友寻求帮助如何通过脚本动态控制LINUX系统的内存占用百分比经过一番百度编写调试,终于初步完成了动态控制LINUX系统内存占用百分比。现写出来以帮助更多的朋友。1前言根据需求是动态控制LINUX系统内存占用百分比,比如当前内存占用30,如果设置内存占用为70,则需要申请内存使达到占用70;如果再降低到40,则需要释放部分申请的内存。其实脚本的本质是内存动态申请与释放。注意因为PYTHON脚本运行之前内存有一定占用,故设定内存占用不能低于该百分比。2内存动态申请通过查询资料,使用PYTHON动态申请内存块,可以使用CTYPES包中的函数,导入包及代码如下所示FROMCTYPESIMPORTMEMCREATE_STRING_BUFFER1024说明内存申请使用CREATE_STRING_BUFFER函数,上面申请了1024字节的内存块。下面演示申请100MB内存前后变化申请前如下图所示使用代码如下MEMCREATE_STRING_BUFFER104857600申请后如下图所示从上述两幅图中可以看出,申请内存前内存占用295MB,申请后内存占用397MB,增加了约100MB内存占用。3内存动态释放由于PYTHON对内存是有垃圾回收机制的,采用对象引用计数方式。当对象的引用计数为0时,启动垃圾回收GC。此处内存动态释放就是使用该原理。代码如下MEMNONE释放后内存占用如下图所示内存占用由397MB降低到297MB,释放了100MB内存占用。说明将NONE赋值给对象MEM后,MEM对象的引用计数即为0,此时垃圾回收启动,释放MEM对象占用的内存。4系统总内存、占用内存检测由于需要设定内存占用百分比,故需要获取系统总物理内存和占用内存。本文使用的方法是读取系统文件“/PROC/MEMINFO”,从中解析出总内存大小以及当前内存占用大小等内存相关的信息。该文件内容格式如下图所示代码片段如下所示“/PROC/MEMINFO“LINESFREADLINESFCLOSEFORLINEINLINESIFLENLINEMBN10241024USEDFLOATMEMMEMUSED/NTOTALFLOATMEMMEMTOTAL/NRATEUSED/TOTAL100SMP{USEDUSED,TOTALTOTAL,RATERATE}RETURNSMPDISPLAYCURRENTMEMORYINFODEFPRINT_MEMORY_INFOMEMGETSIMPLEMEMORYINFOSMPGET_MEMORY_INFOMEMPRINT“USEDMBD\TTOTALMBD\TUSEDRATED“SMPUSED,SMPTOTAL,SMPRATEGETRATEOFMEMORYUSEDTOBESETTEDINTEGERATEDEF_MEMORY_USED_RATEORG_RATEBYTEMBN10241024WHILETRUEMEMGET_MEMORY_STATPRINT_MEMORY_INFOMEM_STRRAW_“USEDMEMORYSRATEORQTOEXIT“IFLEN_STR0CONTINUEIF“Q“_STRINFO{RATE0,USEDMEMMEMUSED/N}RETURNINFOIF“Q“_STRINFO{RATE0,USEDMEMMEMUSED/N}RETURNINFOTRYRATEFLOAT_STRIFRATEORG_RATEANDRATEPRE_USEDCUR_USEDPRE_USEDWHILETRUETOCALCFREEMEMORYORALLOCATEMEMORYNEED_NEWDEST_MEMN_CHGPRE_USEDNEED_DELDEST_MEMN_CHG0PLISTIDXDELLISTIDXPNONEDEST_MEMDEST_MEMN_CHGCUR_USEDCUR_USEDN_CHGELSERETURN“END“PRINT“MEMORYUSEDMBD“CUR_USEDENTRYOFPROGRAMLISTOFMEMORYOBJECT,10MBOFONEOBJECTLISTGETCURRENTMEMORYINFOMEMGET_MEMORY_STATGETSIMPLEMEMORYINFOSMPGET_MEMORY_INFOMEMORG_RATESMPRATETOTALSMPTOTALWHILETRUEGETRATEOFMEMORYTOBEUSEDINFO_MEMORY_USED_RATEORG_RATENEW_RATEFLOATINFORATEPRE_USEDFLOATINFOUSEDSETRATEOFMEMORYTOBEUSEDRTNSET_MEMORY_USED_RATENEW_RATE,TOTAL,PRE_USED,LISTIFNOTRTNPRINT“BYE“EXIT