python垃圾回收,判断内存占用,手动回收内存,二

Posted 北风之神0509

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python垃圾回收,判断内存占用,手动回收内存,二相关的知识,希望对你有一定的参考价值。

以下为例子,判断计算机内存并释放程序内存。

# coding=utf8
import time
import psutil, gc, commands

from logger_until import LoggerUntil
from until import keep_circulating

logger = LoggerUntil(name="Monitor").getlog(logfilename=Monitor.log, loglevel=2, add_StreamHandler=1)

need_monitor_procces_names = [  ##需要检测的进程的cmd命令放到这里,支持模糊匹配
    touna0627.py,
    dailiip.py,
    redis-server,
    mongod,
]


class Monitor(object):
    def __init__(self):
        self.specified_process_list = self.get_specified_process()
        self.current_process = self.get_current_process()

    @staticmethod
    def print_all_cmdlines():
        for pid in psutil.pids():
            p = psutil.Process(pid)
            print p.cmdline()

    @staticmethod
    def get_specified_process():
        all_pids = psutil.pids()
        process_list = []
        for pid in all_pids:
            p = psutil.Process(pid)
            p_cmdline = p.cmdline()
            for argx in p_cmdline:
                for name in need_monitor_procces_names:
                    if argx.find(name) > -1:
                        if p.status() != stopped:
                            process_list.append(p)

        p_pid_set = set()
        process_list2 = []
        for p in process_list:
            if p.pid not in p_pid_set:
                process_list2.append(p)
                p_pid_set.add(p.pid)
        return process_list2

    @staticmethod
    def monitor_system():
        psutil.cpu_percent()
        time.sleep(1)
        mem = psutil.virtual_memory()

        mem_total = mem.total / 1000000
        mem_available = mem.available / 1000000
        mem_percent_str = str(mem.percent) + %

        cpu_count = psutil.cpu_count()
        cpu_percent_str = str(psutil.cpu_percent()) + %

        msg = 本机总内存是:{0}M , 本机可用内存是:{1}M, 本机内存使用率是:{2}, 本机cpu核数是:{3}, 本机cpu使用率是:{4}\n\n.format(mem_total, mem_available, mem_percent_str, cpu_count, cpu_percent_str)
        logger.info(msg)

    def monitor_specified_process(self):
        for p in self.specified_process_list:
            p.cpu_percent(None)
        time.sleep(1)
        for p in self.specified_process_list:
            # p = psutil.Process(0)
            """:type :psutil.Process"""
            cmdline_str =   .join(p.cmdline()).ljust(60,  )
            p_cpu_percent_str = str(round(p.cpu_percent(), 2)) + %
            p_memory_percent_str = str(round(p.memory_percent(), 2)) + %
            p_strated_time = time.strftime(%Y-%m-%d %H:%M:%S, time.localtime(p.create_time()))
            p_pid_str = str(p.pid)

            msg = 进程 + cmdline_str +  的pid是: + p_pid_str +   cpu使用率是: + p_cpu_percent_str +   内存使用率是: + p_memory_percent_str                   +   进程的启动时间是: + p_strated_time
            logger.info(msg)

    @staticmethod
    def get_current_process():
        return psutil.Process()

    def is_need_release(self,threshold):
        print self.current_process.memory_percent()
        if self.current_process.memory_percent() < threshold:
            return 0
        else:
            logger.info(回收当前 %s 进程id的内存 % self.current_process.pid)
            return  1

    def free_current_process_memory(self, threshold):
        """回收python所处的当前进程的内存"""
        if self.is_need_release(threshold) == 1:
            gc.collect()

class MemoryReleaser():
    def __init__(self,threshold):
        self.threshold = threshold
        self.stutus, self.output = self.__get_memory_available()

    @staticmethod
    def __get_memory_available():
        status, output = commands.getstatusoutput("free -m | grep Mem | awk  ‘{print $7}‘")  ##shell命令查询计算机可用内存
        return  status, output

    def release_memory(self):
        if float(self.output) < self.threshold:
            logger.info(计算机可用内存是 %sM ,程序需要释放内存%self.output)
            gc.collect()

@keep_circulating(10)
def monitoring():
    MemoryReleaser(600).release_memory()     ###这一行来释放内存
    monitor = Monitor()
    monitor.monitor_specified_process()
    monitor.monitor_system()

if __name__ == "__main__":
    pass
    a = list(range(10000000))
    del a
    monitoring()

 

如果把MemoryReleaser(600).release_memory() 注释掉,程序将一直是占用大内存。

 

程序中使用了 

free -m | grep Mem | awk  ‘{print $7}‘
来判断计算机可用内存。

虽然psutil可以判断内存,但使用psutil判断内存,内存就无法回收了。

把MemoryReleaser(600).release_memory() 放到monitoring函数中的最后一行,那就回收不了内存了。


尝试了很多次使用
 if psutil.Process().memory_percent() > 0: 
  gc.collect()

这种方式不能回收内存。
写成if true是可以回收内存的。



 















以上是关于python垃圾回收,判断内存占用,手动回收内存,二的主要内容,如果未能解决你的问题,请参考以下文章

虚拟机GC的定义

python垃圾箱-垃圾回收

Java的垃圾回收机制

内存泄漏与垃圾回收机制

JVM专题--垃圾回收算法, 垃圾回收器

Python之垃圾回收机制与用户交互