繁体   English   中英

释放Python中的threading.Timer内存

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

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

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

下面是代码。 对不起,大代码。 我想最好让整个代码知道我是否缺少某处。

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 如何释放已过期或已取消的计时器的内存?

编辑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

删除后, self.pktinfo的元素self.pktinfo减少。 self.pktinfo的大小在很长一段时间内保持不变,但最终会改变(减小或增大)。 但是系统的内存似乎并没有释放。 top显示的行为与程序所使用的内存在不断增加。

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

暂无
暂无

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

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