Repository: vispy/vispy

Issue:
memory surge after minimizing the vispy window
Hi, thank you very much for working on vispy. Recently, I found a bug related to memory consumption. It appears after minimizing the vispy window, with a memory surge rate of about 50 MB/second. This surge doesn't exist even if you bring other programs to the top level. The only way to trigger it, based on my experience so far, is to minimize the window by either clicking the "Minimize" icon on the window or the taskbar icon of the vispy window. 

Please try the two scripts provided in the Examples folder in the vispy github: Examples\demo\scene\scrolling_plots.py and Examples\demo\gloo\realtime_signals.py

Below is my environment:
OS: Windows 10 ver.1909
Python: 3.8.3
vispy: 0.6.4 or github master
pyqt5: 5.14.2

Thanks! Appreciate the help. 



Discussion:
That's...crazy. I got the same results when running the scrolling_plots.py example on my Ubuntu machine with Python 3.7. What seems to be the (obvious?) problem is that vispy, while being minimized, is telling the GPU to update with new data but since the window isn't visible the GPU isn't drawing it or PyQt5 is building up a queue of draws (or drawing events) and they're filling up memory.

Not really sure how to tackle this one. We might need to figure out first whether this is PyQt5 only or if this happens with other backends. Another thing to check would be to find out what is actually filling up memory.
I did a quick test of changing the scrolling lines timer to a 5 second update interval and the memory increase is still there just much slower.
Thanks, David, for quick responses. Just tried app.use() to change backends for the app. No surge for glfw and pyglet, but not for pyqt5. So, it's related to pyqt, which unfortunately is mandatory in my software. Could anyone fix the problem with pyqt5 backend?
With pyqt5, it also uses much higher cpu as well. In my case, pyqt5 consumes 8.5% cpu, but pyglte only consumes 1.5% cpu. All these cpu tests were performed with the vispy window visible on the top. 
> Could anyone fix the problem with pyqt5 backend?

So far based on your tests and my own tests I don't see anything that says this is something we (vispy) can fix ourselves. It's possible this is something in PyQt5 that we don't have control over. That said, I'm sure we can come up with a workaround.

In your application, are you seeing this because you have a timer that is updating the visuals? Do you have the option to *not* update the visuals if you detect that the window is minimized?

Regardless, someone (not sure I'll have time right now) could try playing with PyQt's process events (processEvents) in specific places in the timer function or in the backend to see if this fixes the issue. I wonder if telling Qt "I don't care that we aren't being shown, keep drawing stuff". There may be other Qt flags that control this logic so processEvents wouldn't be needed.
I did playing with processEvents in the timer, but it didn't work out in the end. Currently, as you said, vispy updates are disabled once the window is minimized. Thanks.

Resolving patch:
diff --git a/examples/demo/gloo/realtime_signals.py b/examples/demo/gloo/realtime_signals.py
--- a/examples/demo/gloo/realtime_signals.py
+++ b/examples/demo/gloo/realtime_signals.py
@@ -155,6 +155,7 @@ def on_timer(self, event):
 
         self.program['a_position'].set_data(y.ravel().astype(np.float32))
         self.update()
+        self.context.flush()  # prevent memory leak when minimized
 
     def on_draw(self, event):
         gloo.clear()
diff --git a/examples/demo/scene/scrolling_plots.py b/examples/demo/scene/scrolling_plots.py
--- a/examples/demo/scene/scrolling_plots.py
+++ b/examples/demo/scene/scrolling_plots.py
@@ -41,6 +41,7 @@ def update(ev):
     data = np.random.normal(size=(N, m), scale=0.3)
     data[data > 1] += 4
     lines.roll_data(data)
+    canvas.context.flush()  # prevent memory leak when minimized
 
 timer = app.Timer(connect=update, interval=0)
 timer.start()


Test patch: