在Python中释放threading.Timer的内存 [英] Release the memory of threading.Timer in Python

查看:715
本文介绍了在Python中释放threading.Timer的内存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在用scapy进行数据包注入,并创建一个threading.Timer,它将在10秒后从字典中删除数据包信息. 如果我在10秒钟前收到响应,则取消Timer并从字典中删除数据包信息.由于我要取消计时器,因此可以在此处放置.join().但是,当计时器到期时,.join()没有任何机制.

I'm doing a packet injection with scapy and creating a threading.Timer which deletes the packet information from the dictionary after 10 seconds. If I receive a response before 10 seconds, I'm cancelling the Timer and deleting the packet information from the dictionary. Since I'm cancelling the Timer, I can put .join() here. But when the Timer expires, there's no mechanism to .join().

当我运行程序时,内存不断增加.毫无疑问,增长速度很慢(最初在1 GB RAM系统中为2%.在20分钟内达到3.9%).但它仍在继续增长.我尝试了gc.collect().但这没有帮助.我正在用top监视内存.

When I run the program, the memory keeps on increasing. No doubt, increasing is slow (Initially 2% in a 1 GB RAM system. In 20 minutes, it went to 3.9%). But still it keeps on increasing. I tried gc.collect(). But it's of no help. I'm monitoring the memory with top.

下面是代码.抱歉,输入的代码过大.我想最好让整个代码知道我是否在某处缺少什么.

Below is the code. Sorry for the large code. I guess it's better to give the whole code to know if somewhere I'm missing something.

from threading import Timer
from scapy.all import *
import gc

class ProcessPacket():
    #To write the packets to the response.pcap file    
    def pcapWrite(self, pkts):
        writerResponse(pkts)
        writerResponse.flush()
        return

    #cancels the Timer upon receiving a response
    def timerCancel(self, ipPort):
        if self.pktInfo[ipPort]["timer"].isAlive():
            self.pktInfo[ipPort]["timer"].cancel()
            self.pktInfo[ipPort]["timer"].join()  
        self.delete(ipPort)
        return

    #deletes the packet information from pktInfo
    def delete(self, ipPort):
        if self.pktInfo.has_key(ipPort):
            self.pcapWrite(self.pktInfo[ipPort]["packets"])
            del self.pktInfo[ipPort]
        return

    #processes the received packet and sends the response
    def createSend(self, pkt, ipPort):
        self.pktInfo[ipPort]["packets"] = [pkt]
        self.pktInfo[ipPort]["timer"] = Timer(10, self.delete, args=[ipPort])        
        myPkt = IP(src = pkt[IP].dst, dst = pkt[IP].src)/ TCP(dport = pkt[TCP].sport, sport = pkt[TCP].dport, flags = 'SA')
        self.pktInfo[ipPort]["packets"].append(myPkt)        
        send(myPkt, verbose=0)
        self.pktInfo[ipPort]["timer"].start()
        return

    #constructor
    def __init__(self):
        self.count = 0
        self.writerResponse=PcapWriter('response.pcap',append = True)
        self.pktInfo = {}
        return

    #from sniff
    def pktCallback(self,pkt):    
        ipPort = pkt[IP].src + str(pkt[TCP].sport) + pkt[IP].dst + str(pkt[TCP].dport)
        flag=pkt.sprintf('%TCP.flags%')
        if self.count == 10:
            self.count = 0
            gc.collect()
        if not self.pktInfo.has_key(ipPort) and flag == 'S':
            self.pktInfo[ipPort] = {}
            self.createSend(pkt, ipPort)
            self.count += 1
        elif self.pktInfo.has_key(ipPort):
            self.timerCancel(ipPort)
            self.count += 1
        return

#custom filter for sniff
def myFilter(pkt):
    if pkt.haslayer(IP):
        if pkt[IP].src == "172.16.0.1":
            return 1
        return 0                

if __name__ == '__main__':      
    respondObj = ProcessPacket()
    sniff(iface = 'eth0', filter = "tcp", prn = respondObj.pktCallback, lfilter = myFilter)

在程序中,除了pktInfoTimer之外,我没有看到其他任何占用内存的因素. pktInfo正在增加和减少,因此问题出在Timer上.如何释放已过期或已取消的计时器的内存?

In the program, I don't see any other memory consuming factor other than pktInfo and the Timer. pktInfo is increasing and decreasing so the problem is with Timer. How can I free memory of the expired or cancelled Timers?

我修改了delete()函数:

#deletes the packet information from pktInfo
def delete(self, ipPort):
    if self.pktInfo.has_key(ipPort):
        print "Before", len(self.pktinfo.keys()), sys.getsizeof(self.pktinfo)
        self.pcapWrite(self.pktInfo[ipPort]["packets"])
        self.pktInfo[ipPort]["timer"]=None
        self.pktInfo[ipPort]=None
        del self.pktInfo[ipPort]
        gc.collect()
        print "After", len(self.pktinfo.keys()), sys.getsizeof(self.pktinfo)
    return

删除后,self.pktinfo中的元素数量减少. self.pktinfo的大小会长时间保持不变,但最终会发生变化(减小或增大).但是系统的内存似乎没有被释放. top表现出与程序使用的内存不断增加相同的行为.

After deletion the number of elements in self.pktinfo decreases. The size of the self.pktinfo remains same for a long time but eventually changes (decreases or increases). But the memory of system doesn't seem to be released. top shows the same behaviour that the memory used by the program is continuously increasing.

推荐答案

释放对不需要的Timer对象的所有引用. (例如self.pktInfo[ipPort]["timer"] = None)-如果您不这样做,垃圾收集器将不会释放任何东西.

Release all references to unneeded Timer objects. (e.g. self.pktInfo[ipPort]["timer"] = None) - if you don't the garbage collector won't free up anything.

这篇关于在Python中释放threading.Timer的内存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆