zoukankan      html  css  js  c++  java
  • python垃圾回收,判断内存占用,手动回收内存,二

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

    # coding=utf8
    import time
    import psutil, gc, commands,os
    
    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}
    
    '.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,cmd_name_str='touna0627.py'):
            """
            :type  threshold:float
            """
            self.threshold = threshold    # 内存使用率的阈值
            self.cmd_name_str =cmd_name_str
            self.stutus, self.output = self.__get_memory_available()
    
    
        def __get_memory_available(self):
            # status, output = commands.getstatusoutput("free -m | grep Mem | awk  '{print $4}'")  ##shell命令查询计算机可用内存
            status, output = commands.getstatusoutput("ps aux | grep %s  | sort -k4,4nr|head -1| awk '{print $4}'"%(self.cmd_name_str))  ##shell命令查询程序的内存使用率
            return  status, output
    
        def release_memory(self):
            if float(self.output) > self.threshold:
                logger.info('程序的内存使用率是 {}% ,程序需要释放内存'.format(self.output))
                gc.collect()
    
    @keep_circulating(10)
    def monitoring():
        MemoryReleaser(40).release_memory()     ###这一行来释放内存
        monitor = Monitor()
        monitor.monitor_specified_process()
        monitor.monitor_system()
    
    if __name__ == "__main__":
        pass
        a = list(range(10000000))
        del a
        time.sleep(30)
        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是可以回收内存的。



  • 相关阅读:
    报错Required String parameter 'customerInfo' is not present的原因及处理办法
    Mybatis 中$与#的区别
    ON DUPLICATE KEY UPDATE单个增加更新及批量增加更新的sql
    Git使用
    前后端分离
    对excel文件的读取
    POI导入和导出Excel总结
    git权限
    @RequestParam与@PathVariable
    lombok学习
  • 原文地址:https://www.cnblogs.com/ydf0509/p/8053114.html
Copyright © 2011-2022 走看看