释放记忆线程。计时器在Python中

2024-04-26 06:15:19 发布

您现在位置:Python中文网/ 问答频道 /正文

我用scapy进行包注入,并创建一个threading.Timer,它在10秒后从字典中删除包信息。 如果我在10秒前收到响应,我将取消Timer并从字典中删除包信息。既然我取消了计时器,我可以把.join()放在这里。但是当计时器过期时,没有机制.join()。在

当我运行程序时,内存不断增加。毫无疑问,增长是缓慢的(在1GB RAM系统中最初是2%)。在20分钟内,它达到了3.9%。但它仍在继续增长。我试过了。但没用。我用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)

在程序中,除了pktInfo和{}之外,我没有看到任何其他的内存消耗因素。pktInfo在增加和减少,所以问题出在{}。如何释放过期或取消计时器的内存?在

编辑1: 我修改了delete()函数:

^{pr2}$

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


Tags: the内存fromselfipreturnifdef