Hi Tangoers!
I’ve been facing quite an annoying problem with my device server. Problem generally known as a memory leak :-O. After a long time I manage to separate a few lines out of my code which were responsible of memory consumption. To my surprise, any call to ProxyList object was causing the device server to consume more and more memory.
I attach the Device Server class(DeviceTest.py), where comments point to each line where the ProxyList object was used.
The leak can be observed while using such an example script, which just reads attributes in a loop. (I also tested the behavior when using commands, but it is same- leaking).
import time
from PyTango import DeviceProxy
dev = DeviceProxy("test/devicetest/test")
while True:
test = dev.test_attr_2
print test,'.'
time.sleep(0.01)
My next step was to test the same approach while using simple python script (without Tango), but memory usage didn’t grow. (script.py)
I used a memory_profiler module to trace the leak and currently working on Python2.7 with PyTango 9.3.1 on a Windows10 machine.
Any help would be appreciated. Maybe I’m missing something here…
FYI, the reason of using multiprocessing was to separate device communication and device memory read to another process. Device Server just shares variables with the second process. For example using
self.data_counter = multiprocessing.Value('i', 0)
and returning its value
return self.data_counter.value
in attributes doesn’t cause a memory leak.
So in my case I created
self.current_memory = self.manager.list()
passed this to a process, started it and assigned values to this list within a process, so that attribute could return
[self.current_memory[registry], self.get_dataCounter()]
As tutorials point, this seems to be a proper list usage while using multiprocessing and manager caring of memory sharing.
What is more, the reason why I use ListProxy is that it can increase its size after creation - in contrary to
multiprocessing.Array("i", [0, 1])
where one has to specify its size on the very beginning. In my case user can decide in runtime which registers are read in the second process.
Anyway, I would be very grateful for helping me with a solution to my problem.