[英]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
. 在程序中,除了pktInfo
和Timer
之外,我看不到任何其他内存消耗因素。 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.