O
O
oo22maxi2021-07-05 19:01:14
Python
oo22maxi, 2021-07-05 19:01:14

Memory leak using Thread and pyglet?

Good evening. I can not understand what is the problem, why does the memory increase every time the next mp3 file is started?

import threading, pyglet, time

class Player():
    
    def __init__(self):
        super(Player, self).__init__()
        self.sound = False

    def run(self):
        self.sound = pyglet.media.Player()
        self.player_thread = threading.Thread(target=self.playsound)
        self.player_thread.start()

    def playsound(self):
        # Путь к mp3 файлу
        music = pyglet.media.load(r'/home/app/sound.mp3')
        self.sound.queue(music)
        self.sound.play()
        pyglet.app.run()

    def next(self):
        n_thread =  threading.active_count()
        print(f'Thread count: {n_thread}')
        for t in threading.enumerate():
            print(f'Thread Name: {t.name}')
        
        self.sound.delete()
        del self.sound
        pyglet.app.exit()
        del self.player_thread
        self.run()
        

    def exit(self):
        self.sound.delete()
        del self.sound
        self.sound = False
        pyglet.app.exit()


p = Player()

print("Выберите действие")
while True:
    # play - Старт плеера
    # next - Следующий трек
    # stop - Остановка трека
    # exit - Выход из программы
    x = input('play (p) | next (n) | stop (s) | exit:\n')
    if x == 'play' or x == 'p':
        p.run()
    elif x == 'next' or x == 'n':
        p.next()
    elif x == 'stop' or x == 's':
        if p.sound:
            p.exit()
    elif x == 'exit':
        if p.sound:
            p.exit()
        break
    else:
        print("Выберите действие")

Answer the question

In order to leave comments, you need to log in

2 answer(s)
O
oo22maxi, 2021-07-07
@oo22maxi

I found a solution, it was necessary to use not a separate thread through threading.Thread, but a separate process through multiprocessing.Process. When playing the next track, the process closes and a new one opens, resulting in no memory leak.

S
Stefan, 2021-07-05
@MEDIOFF

I do not pretend to be truthful, but as far as I know, things are like this.
Python stores objects in pools, and pools in arenas, this is to avoid smearing data in memory, when python is looking for where to push an object, it looks for empty arenas, and if there are none, it requests it from the system. If we have free arenas, it selects the most populated arena and writes our object there (again, so that the data is not spread over memory, but stored as close as possible). When the arena is filled in this way, it takes the next one, but the trick is that when we delete a large object from memory (and in this case, an mp3 file can take up the entire arena from us at once), then python does not return this arena to the system, and it remains with programs further, from here it is possible that this is happening to you
PS: if you are interested in a video about how memory works in python, this is explained in some detail tick

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question