在 Kivy 中,为啥 popup.dismiss() 不从内存中删除弹出窗口?
Posted
技术标签:
【中文标题】在 Kivy 中,为啥 popup.dismiss() 不从内存中删除弹出窗口?【英文标题】:In Kivy, why doesn't popup.dismiss() delete the popup from memory?在 Kivy 中,为什么 popup.dismiss() 不从内存中删除弹出窗口? 【发布时间】:2016-01-10 07:36:27 【问题描述】:我目前正在努力解决 Kivy 中的内存使用问题。
当一个弹出窗口被创建和打开时,内存使用量会增加一点(这是正常的),但是当用户关闭它时(使用dismiss()方法,关闭弹出窗口并将其从其父级中删除),内存没有释放。
因此,如果用户决定多次打开弹出窗口,程序最终会占用大量内存。这是我的代码的一部分,它通过创建、打开然后关闭弹出窗口 500 次来显示问题。
# py file
class OptionsView(Screen):
def popupLoop(self):
for x in range(0, 500):
popup = self.MyPopup()
popup.open()
popup.dismiss()
class MyPopup(Popup):
pass
# kv file
<OptionsView>:
BoxLayout:
orientation: "vertical"
Button:
text: "Popup Loop"
on_press: root.popupLoop()
<MyPopup>:
size_hint: (.6, .6)
title: "Confirmation"
BoxLayout:
Button:
text: "Cancel"
on_press: root.dismiss()
在 OptionView 屏幕中按下“Popup Loop”按钮会使程序的内存使用率从 1.2% 跃升至 11.7%(根据 top
)。调整窗口大小(调用gc.collect()
)确实使这个数字降低了一点,但仍然很高。
如何防止这种情况发生? (请记住,我远不是 Python/Kivy 专家,所以即使解决方案对您来说真的很明显,请尝试向我解释!)
【问题讨论】:
CPython 可能只是保留内存以备将来使用。尝试打开和关闭 10,000 个弹出窗口。 @Joonazan 好吧,我不知道我的预期。 10 000 个弹出窗口只是让程序崩溃,没有任何错误。我可能只有 4GB 的 RAM,但这种行为仍然很不正常。 它们是同时打开的吗?如果一次只打开一个并且程序仍然崩溃,那么您就有内存泄漏。这在 Python 中是不可能的,但是这个库可能有问题或者需要你调用一些函数来释放内存。 @Joonazan 这确实是个问题:有时没有弹出窗口出现(所以我假设它们一个接一个地打开和关闭),而有时弹出窗口开始堆积,我不得不关闭他们手动。但在这两种情况下,内存使用量都会激增并且不会下降。我尝试将 gc.collect() 添加到 create/open/dismiss 循环中。这显着减缓了内存使用量的上升,但它仍然达到了非常高的水平并且没有回落。我仍然会检查 Kivy 文档,看看是否有你说的特殊功能。 【参考方案1】:popup.dismiss()
不会立即从内存中删除弹出窗口。
也许这会有所帮助How to force deletion of a python object?
第二;关于为什么有时您的弹出窗口会被关闭而有时不会,您必须了解UI frameworks
需要使用事件进行编程。事件/进展不会以线性方式发生。
使用Clock
更好地测试您要检查的内容
self.pops = 0
Clock.schedule_once(self.test_pops)
def test_pops(self, dt):
if self.pops > 10:
return
self.pops += 1
pup = self.MyPopup()
pup.bind(on_parent=self.dismiss_pup)
pup.open()
def dismiss_pup(self, pup, parent)
# popup was opened, please close it now
pup.unbind(on_parent=self.dismiss_pup)
pup.dismiss()
Clock.schedule_once(self.test_pops)
不过,使用专门针对此的 Web 调试器模块会简单得多。
http://kivy.org/docs/api-kivy.modules.webdebugger.html
【讨论】:
以上是关于在 Kivy 中,为啥 popup.dismiss() 不从内存中删除弹出窗口?的主要内容,如果未能解决你的问题,请参考以下文章
在 kivy 样式文件中使用尖括号时,为啥我不断收到“无效语法”错误?
为啥不可能在 kivy 中制作 Markup TextInput?