[英]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)
在程序中,除了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
减少。 self.pktinfo
的大小在很长一段时间内保持不变,但最终会改变(减小或增大)。 但是系统的内存似乎并没有释放。 top
显示的行为与程序所使用的内存在不断增加。
释放对不需要的Timer对象的所有引用。 (例如self.pktInfo[ipPort]["timer"] = None
)-如果您不这样做,垃圾收集器将不会释放任何东西。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.