KivyMD: Dismissing a list item (to GC)
List items apparently are not garbage collected.
Here is a Hello World like app with two buttons. The big one populates a list with 50 items, the little one clears it. Memory usage inspection I’m running like this:
$ mprof run --include-children python leak.py
...
$ mprof plot --output out.png
The required software is matplotlib and memory-profiler. Whenever you run the test, creating and then clearing the list several times by clicking the buttons, you get a plot like a steadily ascending stairway. How am I supposed to convince Kivy(MD) to release the items no longer needed?
leak.py:
from functools import partial
import kivy
kivy.require("1.11.1")
from kivy.utils import platform
print(f"platform: {platform}")
from kivy.lang import Builder
from kivy.uix.floatlayout import FloatLayout
from kivymd.app import MDApp
from kivymd.uix.tab import MDTabsBase
from kivymd.uix.list import TwoLineAvatarIconListItem
import gc
ACTION_ICON = "eye"
class PowerListItem(TwoLineAvatarIconListItem):
"""The engaged power supply item."""
class TabList(FloatLayout, MDTabsBase):
"""The engaged power supplies tab."""
def surfacing(self, tab_text):
pass
def discover(self, cnt):
ids = MDApp.get_running_app().root.ids
for i in range(cnt):
item = PowerListItem(
text="List Item" + f" {i + 1:>2}", secondary_text="none"
)
ids.ps_list.add_widget(item)
class Contero(MDApp):
def build(self):
return Builder.load_file("leak.kv")
def on_start(self):
self.theme_cls.primary_palette = "Gray"
def discovery_clean(self):
for item in self.root.ids.ps_list.children:
print(f"item: {item.text}")
self.root.ids.ps_list.clear_widgets()
gc.collect()
def discovery_request(self, item_count=50):
self.discovery_clean()
tab_list = self.root.ids.ps_tab_list
tab_list.discover(item_count)
def on_tab_switch(self, instance_tabs, instance_tab, instance_tab_label, tab_text):
"""Called when switching tabs.
"""
instance_tab.surfacing(tab_text)
if __name__ == "__main__":
Contero().run()
leak.kv:
#:kivy 1.11.1
#:import ACTION_ICON __main__.ACTION_ICON
BoxLayout:
orientation: "vertical"
MDTabs:
id: ps_tabs
on_tab_switch: app.on_tab_switch(*args)
TabList:
id: ps_tab_list
text: "flash"
ScrollView:
bar_margin: 5
bar_width: 15
bar_color: .0, .8, .0, 1
bar_inactive_color: .5, .5, .5, 1
effect_cls: "ScrollEffect"
scroll_type: ["bars", "content"]
scroll_distance: 5
scroll_timeout: 50
MDList:
id: ps_list
MDBottomAppBar:
MDToolbar:
id: ps_toolbar
title: "Destroy a list"
icon: ACTION_ICON
type: "bottom"
on_action_button: app.discovery_request()
right_action_items: [ ['minus-box-outline', lambda x: app.discovery_clean()], ]
<PowerListItem>:
IconLeftWidget:
id: item_left
icon: "earth"
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Comments: 32 (17 by maintainers)
@mozesa
This is a good practice advised by the Kivy developers.
@mozesa I have already explained 100 times to you - Kivy never released up memory!