在Python中释放threading.Timer的内存 [英] Release the memory of threading.Timer in Python
问题描述
我正在用scapy
进行数据包注入,并创建一个threading.Timer
,它将在10秒后从字典中删除数据包信息.
如果我在10秒钟前收到响应,则取消Timer
并从字典中删除数据包信息.由于我要取消计时器,因此可以在此处放置.join()
.但是,当计时器到期时,.join()
没有任何机制.
I'm doing a packet injection with scapy
and creating a threading.Timer
which deletes the packet information from the dictionary after 10 seconds.
If I receive a response before 10 seconds, I'm cancelling the Timer
and deleting the packet information from the dictionary. Since I'm cancelling the Timer, I can put .join()
here. But when the Timer expires, there's no mechanism to .join()
.
当我运行程序时,内存不断增加.毫无疑问,增长速度很慢(最初在1 GB RAM系统中为2%.在20分钟内达到3.9%).但它仍在继续增长.我尝试了gc.collect()
.但这没有帮助.我正在用top
监视内存.
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%). But still it keeps on increasing. I tried gc.collect()
. But it's of no help. I'm monitoring the memory with 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)
在程序中,除了pktInfo
和Timer
之外,我没有看到其他任何占用内存的因素. pktInfo
正在增加和减少,因此问题出在Timer
上.如何释放已过期或已取消的计时器的内存?
In the program, I don't see any other memory consuming factor other than pktInfo
and the Timer
. pktInfo
is increasing and decreasing so the problem is with Timer
. How can I free memory of the expired or cancelled Timers?
我修改了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
表现出与程序使用的内存不断增加相同的行为.
After deletion the number of elements in self.pktinfo
decreases. The size of the self.pktinfo
remains same for a long time but eventually changes (decreases or increases). 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.
推荐答案
释放对不需要的Timer对象的所有引用. (例如self.pktInfo[ipPort]["timer"] = None
)-如果您不这样做,垃圾收集器将不会释放任何东西.
Release all references to unneeded Timer objects. (e.g. self.pktInfo[ipPort]["timer"] = None
) - if you don't the garbage collector won't free up anything.
这篇关于在Python中释放threading.Timer的内存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!