是什么导致使用kivy导致代码泄漏?

时间:2019-03-16 02:09:24

标签: python kivy

我很烦标题的麻烦。我在下面的代码中根据代码结构缩短了代码。该代码假定保存为文件名“ 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”的行。注意行上写的命令似乎增加了内存大小。以下两个“十大差异”显示了早期和晚期的结果。例如,“ revival_memory_leak.py:37”,它指示文件revival_memory_leak.py的第37行,内存大小从179KiB增加到276KiB。为什么不释放内存?我以为当调用remove_group方法时,绘图对象(例如Rectangle)的内存释放。
  • “早期”的内存消耗

[ 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 个答案:

答案 0 :(得分:0)

我似乎已经解决了使用InstructionGroup类的问题,而不是直接将图形项添加到画布中。谢谢您的合作。