управление памятью python и ctypes - PullRequest
0 голосов
/ 23 февраля 2020

Я использую python 3.7.3 и numpy 1.18.

Если у меня есть базовый класс:

class A:
    does stuff

, а затем производный класс:

class B:
    def __init__(self, A):
        creates numpy arrays
        self.objective_fn = A.function_name

будут ли массивы numpy собираться мусором, как только класс B покинет область действия? Или, поскольку класс B содержит ссылку на класс A, мне нужно будет подождать, пока класс A выйдет из области видимости для python, чтобы собрать эту память? Кроме того, я думаю, что указатель c на один из массивов B больше не будет указывать на эти данные после того, как python мусор соберет np-массивы, верно?


Прямо сейчас я есть класс worker A, который просто сидит и слушает работу - этот класс не покинет область действия, пока программа не завершится. Когда он находит работу, рабочий класс собирает необходимую информацию, создает производный класс B (рабочий) и затем связывается с типами c через c для выполнения работы.

Я заметил утечку памяти и через профилировщик подтвердил, что единственное место, которое действительно добавляет память, - это когда я вызываю функцию C_bound.

#A rough sketch of the code condensed into one loop: (right now this is in three different functions/classes/files) 

worker = Child(id)

while worker.alive():
    if worker.hasTask():
         #... collect information from disk
         o = Optimizer(worker) # creates some numpy arrays
         c_bound_fn(o.objective_fn,  # callback function
                    o.popsize, 
                    ... # algorithm arguments
                    o.create_population().ctypes.data_as(c.POINTER(c.c_double)), # init population
                    o.init_fitness.ctypes.data_as(c.POINTER(c.c_double)),
                    o.collect_output) # call back function
         save_results(o)
         answer = {worker.evaluate(o.best), o.best, ...}
         worker.return_answer(answer)

Класс worker/child должен оставаться в живых, потому что он хранит в памяти объект симулятора, который стоит дорого (~ 1 ГБ ОЗУ), и я не хочу постоянно строить и разрушать эти объекты и вместо этого просто обновлять параметры.

Если вы хотите увидеть действительный код: рабочий класс (в строке, куда я добавляю производный класс): https://github.com/aadharna/UntouchableThunder/blob/71dcc5aca23628c90e4b704a2713ccf6e69b99b4/utils/ADPChild.py#L128

worker-creation и бегун: https://github.com/aadharna/UntouchableThunder/blob/master/child.py

Класс взаимодействия оптимизации и Точка взаимодействия с c -привязками: https://github.com/aadharna/UntouchableThunder/tree/master/optimization

python в c пакет: https://github.com/omardelarosa/Adaptive-DEs/tree/f2ffd98319335b54d092ac7f2ae6617bb7d5da2b


снимки экрана профилировщика:

enter image description here

...