#python #kivy
#python #kivy
Вопрос:
Меня беспокоит проблема с заголовком. Ниже я показал, что мой код сокращен в соответствии с его структурой кода. Предполагается, что код будет сохранен как filename «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()
-
Результат:
- Пожалуйста, обратите внимание на строки, записанные как «revival_memory_leak.py «. Команда, написанная в строках внимания, казалось, увеличила объем памяти. Приведенные ниже два «Топ-10 отличий» показывают результат ранней стадии и более поздней стадии. Например, «revival_memory_leak.py:37», который указывает на строку 37 файла revival_memory_leak.py объем памяти был увеличен до 276 КБ с 179 КБ. Почему бы не освободить память? Я думал, что память освобождается для объекта рисования (например, прямоугольника) при вызове метода remove_group.
-
«ранняя стадия» потребления памяти
[ 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
Комментарии:
1. Ваш код выдает ошибку:
NameError: name 'App' is not defined
2. В вашем коде есть ряд проблем. Для этого нужна внешняя библиотека (tracemalloc), и я не думаю, что кто-то собирается устанавливать ее только для проверки. Кроме того, в
__init__
методе ничего нет. И даже если все это исправлено, открывается пустое окно, в котором вообще нет обновлений. Вы ожидаете, что мы сделаем ваш пример за вас?3. Я приношу извинения за неудобства. Код был восстановлен. Код может быть запущен. Заранее благодарю вас.
Ответ №1:
Кажется, я решил свою проблему, используя класс InstructionGroup вместо непосредственного добавления графических элементов в canvas. Спасибо вам за сотрудничество.