2015-04-28 6 views
0

Я делаю инъекцию пакета с scapy и создаю threading.Timer, который удаляет информацию о пакете из словаря через 10 секунд. Если я получаю ответ до 10 секунд, я отменяю Timer и удаляю информацию о пакете из словаря. Поскольку я отменяю Таймер, я могу поставить .join() здесь. Но когда Таймер истекает, нет никакого механизма для .join().Освободите память threading.Timer в Python

Когда я запускаю программу, память продолжает расти. Без сомнения, увеличение происходит медленно (сначала 2% в 1 ГБ оперативной памяти, через 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) 

В программе, я не вижу никакой другой памяти потребляя фактор, кроме pktInfo и Timer. 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 остается таким же в течение длительного времени, но в конечном итоге изменяется (уменьшается или увеличивается). Но память системы, похоже, не выпущена. top показывает то же поведение, что память, используемая программой, постоянно увеличивается.

ответ

0

Отпустите все ссылки на ненужные объекты таймера. (например, self.pktInfo[ipPort]["timer"] = None) - если вы не собираете сборщик мусора, то ничего не освободите.

+0

Пробовал. Кажется, не действует. См. Раздел «Редактировать» вопроса. – RatDon

+0

любые отличия в режиме работы с более длинным временем работы, например, через 30 мин/после 1 часа? – knitti

+0

Я запускаю код около 8-9 часов. Невозможно найти разницу. Или разница незначительна. Возможно ли, чтобы 'top' отображал неверное значение или существует ли какая-либо кеш-память, не выпущенная в ОС? – RatDon

Смежные вопросы