Welcome!
This is the community forum for my apps Pythonista and Editorial.
For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.
debugging possible memory leak
-
I have a scene based script in pythonista which displays a filled graph of values over time.
I implemented this by creating a list of ShapeNode objects. The number of these corresponds to the width of the display area. Each one is setup with ui.Path.rect(0,0,1,height). So each one is 1 pixel wide and the height corresponds to the value being graphed for that point in time. I create the set of ShapeNode objects only once.
Once created, on each scene update, I set the heights of all the ShapeNode objects by assigning a new ui.Path. I did this as I didn't see a way to change the height of an existing ui.Path.
The script seems to work well. But after it runs for a bit (still trying to get more precise timing on that), pythonista exits. My thought is that reassigning a couple hundred ui.Path's on each update may be leaking something.
My understanding is that python should gc these. Is that correct?
-
Is there a better way to adjust the height of the shapenode after it's created?
-
Is there some explicit call I need to release these if re-creating them each time?
-
Any idea on how to show current memory usage for my script so I could turn this functionality on off and see if I am getting continual growth in memory?
-
-
If you just want rectangles, you can use a spritenode with texture =None, but set the color. That will avoid creating hundreds of new textures.
ShapeNodes create a texture from a UI.Path, and probably doesn't do a good job clearing unused textures, especially while the scene is running. (It might be possible to do an auto release pool drain, but better to just avoid the whole thing). You can also resize ShapeNodes to scale them (either with
x_scale
andy_scale
, or withsize
), so you could draw a shape, and just change aspect ratio. Since the UI.Path is converted to an image which then gets scaled, you'd want to draw whatever your largest version first, and scale it down, instead if starting small and scaling it up, otherwise you'd see obvious pixelation.scene
also provides a mechanism https://omz-software.com/pythonista/docs/ios/scene.html#classic-render-loop to do more basic drawing, if you don't need the advanced features if Shape/Sprite nodes like advanced animations, etc.
You can just provide your owndraw
method in scene, and then use scene_drawing methods directly. You get a clean slate every 1/60 sec, and just draw whatever you want in the whole scene. If you have ever used the p5js or the JavaScript in Kahn academy classrs, this will be very familiar. -
@nerdtronn @jonB As the graphic part is only a (monocolor?) filled graphic, I wonder if it wouldn't be better to let the GPU do the display job, using the
shader
functionality of scene, passing values of points via set_uniform. In this case, no problem of memory, isn'it? -
Thanks for the replies and suggestions!
I tried using the approach of creating SpriteNode obs for each vertical slice in the graph and setting their texture to None along with the color as desired. Then, in the update, I just loop through them and set their size to (1, desired_height) and position to the proper place.
On initial testing I noticed artifacts, gaps occasionally between the obs on screen. I bumped the size up to (1.1, desired_height) and that fixed it. Probably rounding errors, etc. causing some gaps. With this in place, it seems to be working and pythonista doesn't crash after awhile since I'm not continually creating new path obs with every update.
The shader approach sounds interesting, seeing that now, but haven't tried it. Will keep that in mind for the future though, maybe worth experimenting with.