How to generate a memory leak in a Python device? [SOLVED]

Is there any known action, bad implementation, classical error, you name it… causing a memory leak in a Python Tango device?

I’m obviously not looking for a way to generate a leak :slight_smile: I’m just wondering if there’s something that could easily explain the memory leak we observe in one of our python devices. The latter is a simple frontend (or facade) which main task is to map and forward attributes of an other device.

So far, we forward the attributes “by hand” forwarding the value read on the underlying device. For instance:

read_forwarded(self, attr):
    da = self.my_dev_proxy.read_attribute(attr.get_name())
    attr.set_value(da.value)

Is there anything wrong in this approach?

Hi Nicolas,

A few memory leaks have been fixed last year, for instance:

If you manage to reproduce it with a simple device, I can run it against the latest version of pytango to check if it has already been fixed. Also, I see you’re not using the pytango high-level API. Any reason why? Here’s what your code would look like with the new API:

@attribute
forwarded(self):
    return self.my_dev_proxy.read_attribute('some_name')

Cheers

Hi Vincent,

Thanks for your help.

We’re still using PyTango-8.1.2 and I suspect we are facing the bug #758.
So, the first thing to do is to switch to the latest version.

Edit: according to our download page, the current PyTango version is 8.0.2 :stuck_out_tongue:
It seems I have to dive into the github repo.

Most attributes of our Frontend device are dynamic. The new API decorators can’t be used in this case.

Hi Nicolas,

I am not sure this is your case, but there is a known memory leak in Tango C++ (not PyTango) if by any chance, you happen to call set_value() more than once in a read request. Something like:


read_forwarded(self, attr):
    da = self.my_dev_proxy.read_attribute(attr.get_name())
    attr.set_value(da.value)
    attr.set_value(da.value)

At the time I discussed with Manu Taurel and we decided it could be considered as bad programming and not necessarily a memory leak.

Not entirely true. Using the new API doesn’t prevent you from doing something like:


from tango.server import attribute

class D(...)

  def init_device(self):
    ...
    voltage = attribute(name='Volt', fget=self.read_v)
    self.add_attribute(voltage)

  def read_v(self, attr):
    attr.set_value(12345)

  @attribute
  def current(self):
      return 4321

It is true that you mix new-style with old-style :-P. I will create an issue in github to be able to handle this case.

Thanks for reporting

Cheers

Thanks Tiago.
I rechecked the code. No double call to ‘set_value’.
I’m compiling pyTango 9…

Good news guys. Switching to PyTango 9.2.2 solves the problem. No more leak!
Thanks.

BTW, are forwarded attributes available in PyTango 9.2.2?