Memory Leak
Marcello-debug opened this issue · 6 comments
Hello!
I tried randomPMU server connected with tinyPDC client. I experienced a memory leak (quite visible also from task manager) that brings to a MemoryError.
O.S. is win7 SP1. Synchrophasor version 1.0.0a0.
Thank you in advance for your help.
Regards
Marcello
Hello @Marcello-debug
Please refer to #20 (comment)
Let us know if you are still encountering this issue on branch bugfix-v1.0.1
.
Thanks!
Thank you @sstevan for your fast and precise response.
Speaking about randomPMU I confirm that introducing a "sleep time" the problem is less evident but still present.
I saw that implementing a sleep time of 20 ms the memory leak rate is 0.5MB/minute.
With a sleep of 1 ms the rate becomes 20 MB/minute
For my application is still not acceptable, have you got any other workaround or suggestion?
Thanks again.
Marcello
@Marcello-debug have tried bugfix branch without adding sleep time?
If you are putting measurements into sending queue faster than the actual reporting rate this "memory leak" is going to appear.
So, if you are having a delay of 20ms before putting measurement into sending queue you are actually creating 50 measurements per second and your reporting rate is 30 measurements per second. This means for each second you will put 20 measurements extra in a queue which will not be sent for that exact second.
That is why putting sleep delay the same as (near) reporting rate will give you better memory usage.
Of course, it takes some time to pack frames for sending and frames are not sent exactly each 1/30s that is why we suggested lowering sending delay for small amount of time that is required to prepare frames for sending.
Thanks again.
I will try to be more clear because I can't understand actually how to overcome the memory leak.
I'm trying the example called randomPMU. I will paste the code at the end of this message. I tried different sleep time but the memory consuption increase for every value of sleep time. For values less then 1/30 s, the memory leak is huge. Over sleep time of 1/30 s the leak is less evident but still present.
Furthermore if I stop a connected PDC, memory increases the rate of consuption and become huge again.
Sorry if I bother you but I'm really interested in this program.
Kind Regards
Marcello
Code:
import random
from synchrophasor.frame import ConfigFrame2
from synchrophasor.pmu import Pmu
import time
"""
randomPMU will listen on ip:port for incoming connections.
After request to start sending measurements - random
values for phasors will be sent.
"""
if __name__ == "__main__":
pmu = Pmu(ip="127.0.0.1", port=1410)
pmu.logger.setLevel("DEBUG")
cfg = ConfigFrame2(1410, # PMU_ID
1000000, # TIME_BASE
1, # Number of PMUs included in data frame
"Random Station", # Station name
1410, # Data-stream ID(s)
(True, True, True, True), # Data format - POLAR; PH - REAL; AN - REAL; FREQ - REAL;
3, # Number of phasors
1, # Number of analog values
1, # Number of digital status words
["VA", "VB", "VC", "ANALOG1", "BREAKER 1 STATUS",
"BREAKER 2 STATUS", "BREAKER 3 STATUS", "BREAKER 4 STATUS", "BREAKER 5 STATUS",
"BREAKER 6 STATUS", "BREAKER 7 STATUS", "BREAKER 8 STATUS", "BREAKER 9 STATUS",
"BREAKER A STATUS", "BREAKER B STATUS", "BREAKER C STATUS", "BREAKER D STATUS",
"BREAKER E STATUS", "BREAKER F STATUS", "BREAKER G STATUS"], # Channel Names
[(0, "v"), (0, "v"),(0, "v")], # Conversion factor for phasor channels - (float representation, not important)
[(1, "pow")], # Conversion factor for analog channels
[(0x0000, 0xffff)], # Mask words for digital status words
50, # Nominal frequency
1, # Configuration change count
30) # Rate of phasor data transmission)
pmu.set_configuration(cfg)
pmu.set_header("This is a PUM server (random data)!")
pmu.run()
while True:
time.sleep(1/30) #riduce consumo cpu e memory leak. Con 0.02s il rate del memory leak è 0.5MB/min. Con 1ms il rate è 20MB/min. Per valori dell'ordine delle decine di ms è più o meno lineare.
pmu.send_data(phasors=[(random.uniform(215.0, 216.0), random.uniform(-0.1, -0.2)), (random.uniform(225.0, 226.0), random.uniform(1.9, 2.0)), (random.uniform(235.0, 236.0), random.uniform(3.0, 3.14))], #3 fasori inmodulo e fase
analog=[9.91],
digital=[0x0001],
freq=10.1) # mHz di scostamento da 50 Hz
pmu.join()
Hey @Marcello-debug
I understand your issue much better now. The issue is caused by stopping the PDC.
We have variable sending_measurements_enabled = False
which is set to False
once the PDC is stopped (command to stop sending is sent). This means you are putting measurements into the buffer but measurements are not getting sent but only stored into the buffer (queue) which is causing increased consumption of RAM.
At this point, there is no elegant way of letting know the feed script (that is generating measurements) that generating should stop. We will add this to our roadmap as a handy feature.
However, what you can do is to try to disconnect the PDC (close connection) and check pmu.clients
list for connections. If it is empty you should stop generating measurements. Not sure if this is going to solve your problem, but you can try and let me know.
Thank you again for your reply.
I have tested your proposals and still the application has two problems:
- Memory leak with one PDC connected (RAM consuption grows with 150 kB / minute rate)
- Big memory leak when a PDC - that was previously connected - disconnect itself (RAM consuption grows with more then 500 kB / minute rate)
Attached you can find my code if you want to test the issues yourself.
Regards
Marcello