我很烦标题的麻烦。我在下面的代码中根据代码结构缩短了代码。该代码假定保存为文件名“ revival_memory_leak.py”。内存泄漏发生在命令return Rectangle(size=...)
等上,由tracemalloc模块发现。有什么技巧可以释放实例生成的Rectangle类的内存吗?
from kivy.uix.widget import Widget
from kivy.graphics import Color, Line, Rectangle
import tracemalloc
from kivy.app import App
from kivy.clock import Clock
from kivy.uix.boxlayout import BoxLayout
from kivy.config import Config
width = 400
height = 300
Config.set('graphics', 'width', str(width))
Config.set('graphics', 'height', str(height))
class MyClass(Widget):
def __init__(self):
super().__init__()
self.cnt_of_loop = 0
self.gid = "1111" # Group ID
self.step_width = 10
self.pos_x = 0
def start(self):
# start loopmethod()
Clock.schedule_interval(self.loop, 0.01)
def get_rectangle(self):
self.pos_x += self.step_width
if self.pos_x >= width:
self.pos_x = self.step_width
# This method returns customized every time kivy.graphics.Rectangle class instance
# The below code seems to cause one of memory leak
return Rectangle(size=(10, 30), pos=(self.pos_x, height / 2), group=self.gid) # generate a Rectangle instance with gid "1111"
def update_canvas(self):
self.canvas.remove_group(self.gid) # clear all canvas items with gid:"1111"
self.canvas.add(Color(1, 0, 1, self.gid))
self.canvas.add(self.get_rectangle()) # add new canvas one more items
def loop(self, dt):
""" This method called repeatedly and infinity """
self.update_canvas()
""" Show difference between used memory and it at step 10"""
if self.cnt_of_loop == 10:
self.snapshot1 = tracemalloc.take_snapshot()
if self.cnt_of_loop > 200:
snapshot2 = tracemalloc.take_snapshot()
top_stats = snapshot2.compare_to(self.snapshot1, 'lineno')
print("[ Top 10 differences]")
for stat in top_stats[:10]:
print(stat)
self.cnt_of_loop += 1
class MyApp(App):
def build(self):
# return MyClass()
a = MyClass()
a.start()
return a
if __name__ == '__main__':
tracemalloc.start()
MyApp().run()
结果:
“早期”的内存消耗
[ Top 10 differences]
revival_memory_leak.py:37: size=179 KiB (+177 KiB), count=2421 (+2396), average=76 B
python3.6/site-packages/kivy/core/window/__init__.py:1343: size=177 KiB (+176 KiB), count=1205 (+1190), average=150 B
revival_memory_leak.py:33: size=140 KiB (+136 KiB), count=4430 (+4345), average=32 B
python3.6/tracemalloc.py:113: size=90.1 KiB (+90.1 KiB), count=1049 (+1049), average=88 B
python3.6/site-packages/kivy/weakmethod.py:56: size=75.8 KiB (+75.0 KiB), count=1078 (+1066), average=72 B
revival_memory_leak.py:53: size=57.8 KiB (+57.8 KiB), count=919 (+919), average=64 B
python3.6/tracemalloc.py:117: size=57.0 KiB (+57.0 KiB), count=912 (+912), average=64 B
revival_memory_leak.py:51: size=55.8 KiB (+55.8 KiB), count=893 (+893), average=64 B
python3.6/site-packages/kivy/cache.py:211: size=18.8 KiB (+18.4 KiB), count=300 (+295), average=64 B
python3.6/site-packages/kivy/clock.py:581: size=14.0 KiB (+11.6 KiB), count=198 (+185), average=72 B
[ Top 10 differences ]
python3.6/site-packages/kivy/core/window/__init__.py:1343: size=283 KiB (+283 KiB), count=1854 (+1839), average=156 B
revival_memory_leak.py:37: size=276 KiB (+274 KiB), count=3732 (+3707), average=76 B
revival_memory_leak.py:33: size=187 KiB (+182 KiB), count=6432 (+6347), average=30 B
python3.6/site-packages/kivy/weakmethod.py:56: size=114 KiB (+113 KiB), count=1623 (+1611), average=72 B
revival_memory_leak.py:53: size=93.5 KiB (+93.5 KiB), count=1490 (+1490), average=64 B
python3.6/tracemalloc.py:117: size=92.6 KiB (+92.6 KiB), count=1482 (+1482), average=64 B
python3.6/tracemalloc.py:113: size=90.4 KiB (+90.4 KiB), count=1052 (+1052), average=88 B
revival_memory_leak.py:51: size=90.0 KiB (+90.0 KiB), count=1440 (+1440), average=64 B
python3.6/site-packages/kivy/cache.py:211: size=34.9 KiB (+34.6 KiB), count=559 (+554), average=64 B
python3.6/tracemalloc.py:387: size=16.2 KiB (+16.2 KiB), count=226 (+226), average=73 B
答案 0 :(得分:0)
我似乎已经解决了使用InstructionGroup类的问题,而不是直接将图形项添加到画布中。谢谢您的合作。