#Running out of memory and I don't comprehend why?

1 messages · Page 1 of 1 (latest)

fringe geode
#

I have a selection menu and the way I am doing it might not be a good idea. Can someone give a quick look at my code and tell me the reason I am running out of memory?

#

Specifically check the bottom half. Lines 192 - 337. I think that's where the issue lies, but my head can't wrap around it as of now.

marble nebula
#

Can you remind us what board you're running this on? Some boards have very little memory to start with.

fringe geode
#

Adafruit ItsyBitsy RP2040

#

It happens when I start pressing buttons and scrolling through the options.

#

I currently believe it's because I am constantly calling functions on top of functions inside the loop??

marble nebula
#

I'm guessing it's because you keep appending new output to splash and never get rid of the stuff that's already appended. append() doesn't get rid of labels you've already shown, it just adds a new one to the end of the list.

#

(which is why it's called "append" 😉 )

#

So everything that you append() while this is running is still there, and never gets released, so you run out of memory.

fringe geode
#

Okay, that is what I was scared of happening. What would I do to fix this?

marble nebula
#

You're going to have to decide how to manage the layers in splash. I don't know what you're going for, you'll have to figure out how to make that work.

Group has pop() and remove() methods to remove items from a group. You could use those. Or you could just assign a new Group to splash, which would get rid of everything that was already there and replace it with the new group. As long as there were no other references to it it would be garbage collected as needed.

fringe geode
#

Errrr. Dang. Someone told me about group the other day but I am such a visual learner that I couldn't find videos on "group" and how it works, so I went ahead with what I did and now I ran into my worry since like day 1.

noble wolf
#

Hi, I just glossed your code and it seems to me that as @marble nebula mentions, you're creating a lot of Label objects. In my experience with UIs in displayio, you create all your objects (Labels in your case) in a setup function and then display them as needed or change their .text attribute if you want to change what the label says.

marble nebula
#

You can make your code work, you just have to remove items from the group when they're no longer in use. Or replace the whole group.

fringe geode
#

Ah, I gotcha. I knew I can make my code work, it will just take me a tad longer.

marble nebula
#

What @noble wolf is suggesting is a good idea. You'd create the labels at the start rather than re-creating them each time you use them.

fringe geode
marble nebula
#

I'm not actually sure what happens if you append a label twice... I'm guessing you'd eventually run out of memory but append might remove the earlier reference (I doubt it though).

#

You separate the creation and the use of the labels. You create each possible label at startup and store it in a variable. Then later when you want to use it you change any attributes you need to (color, x, y, whatever) and append it to the splash

#

But you may still need to manage the layers and remove any unused ones.

fringe geode
#

Well, I tried that and for me it didn't work, let me re-create what I tried doing.

#
splash.append(text_area, text_area2, text_area3, text_area4, text_area5, text_area6, text_area7)

and

splash.append(text_area + text_area2 + text_area3 + text_area4 + text_area5 + text_area6 + text_area7)

Both of those didn't work for me so maybe I am not understanding something?

marble nebula
#

append is when you use the label, not when you create it.

fringe geode
#

Yeah, wouldn't what you just said make the code I just sent append everything? Sorry, it confused me.

marble nebula
#

You only call append when you use the label. So what @noble wolf suggested is you create the labels first. Like:

d4_label = label.Label(terminalio.FONT, text="D4")

You'd do that for each label at the start of your code.

Then when you want to use them you'd do something like:

d4_label.x = col1_variable
d4_label.y = row1_variable
d4_label.color = optionTextColor
splash.append(d4_label)
#

Right now you create a new label every time you use them; the way @noble wolf suggested you'd create each label once and then reuse it, just changing it as needed.

#

What you posted just uses all the labels at once which definitely isn't what you want.

#

append() uses the label

#

label.Label() creates it

noble wolf
# fringe geode ```py splash.append(text_area, text_area2, text_area3, text_area4, text_area5, t...

The technique I use to append a bunch of objects to a Group is:

for t in (text_area, text_area2, text_area3, text_area4):
  splash.append(t)

Also if you have a bunch of related displayio objects, you can put them in a displayio.Group() and then put that single group into your main display group ("splash" in this case), like:

  text_area1 = label.Label(terminalio.FONT, text="D1", ...)
  text_area2 = label.Label(terminalio.FONT, text="D2", ...)
  text_area3 = label.Label(terminalio.FONT, text="D3", ...)
  text_area4 = label.Label(terminalio.FONT, text="D4", ...)
  section1 = displayio.Group()
  for t in (text_area1, text_area2, text_area3, text_area4):
    section1.append(t)
  splash.append(section1)
  section1.hidden = True  # hide every label in this section
fringe geode
#

So, would I use 6 different sections to highlight the background of my selection? Then hide/show each of those sections depending on user input?

#

Here is the screen for reference.

noble wolf
#

You don't have to use the sub-groups if it doesn't make sense for your application. Just another tool in the toolbox

#

you can also hide Labels too, like text_area3.hidden = True if you want to do that

fringe geode
#

Not going to lie, that isn't making sense to me. So sorry, could you elaborate? Like, what do you mean "sub-groups"? 😓

noble wolf
#

The splash variable you've created is a displayio.Group. You can create other Group objects and put them inside splash. Sort of like folders inside of folders in a computer disk. This is what I did in the code snippet above with the "section". It's a Group that's inside of "splash". So I called it a sub-group. If your interface has different "screens" of information, one way to handle that would be each screen of info is a Group that's inside "splash", but only one has ".hidden = False"

marble nebula
#

Using hide is a much better way to do it. (what @noble wolf said :))

fringe geode
#

Okay, well, went through and updated my code and now all it wants to tell me is:

code.py output:
Traceback (most recent call last):
  File "code.py", line 152, in <module>
AttributeError: can't set attribute 'hidden'

Even though I just did a bunch of testing and it was working, then I moved to a different section in my code and I now get this error...

#

Red arrow code works, but then code I'm about to send breaks with that error..

#

This breaks it when run later in the script?