简体   繁体   English

释放Python中的threading.Timer内存

[英]Release the memory of threading.Timer in Python

I'm doing a packet injection with scapy and creating a threading.Timer which deletes the packet information from the dictionary after 10 seconds. 我正在使用scapy进行数据包注入,并创建一个threading.Timer ,它将在10秒后从字典中删除数据包信息。 If I receive a response before 10 seconds, I'm cancelling the Timer and deleting the packet information from the dictionary. 如果我在10秒钟前收到响应,则取消Timer并从字典中删除数据包信息。 Since I'm cancelling the Timer, I can put .join() here. 由于我要取消计时器,因此可以在此处放置.join() But when the Timer expires, there's no mechanism to .join() . 但是,当Timer到期时,没有.join()机制。

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%). 毫无疑问,增长速度很慢(最初在1 GB RAM系统中为2%。在20分钟内达到3.9%)。 But still it keeps on increasing. 但它仍在继续增长。 I tried gc.collect() . 我尝试了gc.collect() But it's of no help. 但这没有帮助。 I'm monitoring the memory with top . 我正在监视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)

In the program, I don't see any other memory consuming factor other than pktInfo and the Timer . 在程序中,除了pktInfoTimer之外,我看不到任何其他内存消耗因素。 pktInfo is increasing and decreasing so the problem is with Timer . pktInfo正在增加和减少,所以出现问题与Timer How can I free memory of the expired or cancelled Timers? 如何释放已过期或已取消的计时器的内存?

EDIT 1: I modified the delete() function: 编辑1:我修改了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

After deletion the number of elements in self.pktinfo decreases. 删除后, self.pktinfo的元素self.pktinfo减少。 The size of the self.pktinfo remains same for a long time but eventually changes (decreases or increases). self.pktinfo的大小在很长一段时间内保持不变,但最终会改变(减小或增大)。 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. top显示的行为与程序所使用的内存在不断增加。

Release all references to unneeded Timer objects. 释放对不需要的Timer对象的所有引用。 (eg self.pktInfo[ipPort]["timer"] = None ) - if you don't the garbage collector won't free up anything. (例如self.pktInfo[ipPort]["timer"] = None )-如果您不这样做,垃圾收集器将不会释放任何东西。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM