0

Следующий код работает отлично и печатает в пустой список (на python3.4):Сборка мусора в питона выдаёт ошибку сегментации кода в то время как `gc.garbage` пуст

import gc 
# code interfacing with C and cython 
print(gc.garbage, flush=True) 

добавляющим эту линию до самого конца марок он сегментации:

gc.collect() 

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

Некоторые поисковые запросы заставили меня поверить, что некоторые из кодов C/Cython создают/уничтожают объекты, не сообщая python, что эти объекты уже удалены из памяти. Затем python пытается удалить их и сработает.

Как я могу найти то, что эти объекты? Я думал, что они будут в gc.garbage перед сбоем, вызывающим gc.collect()?

Или мои предположения полностью неверны?

Предоставление gc.set_debug(gc.DEBUG_STATS | gc.DEBUG_LEAK) к этому коду приводит к исключению python вместо segfault.

---> print(gc.garbage, flush=True) 
    gc.collect() 
... 
ReferenceError: weakly-referenced object no longer exists 

Edit: изменен/упрощена после комментариев от одного из ответов

ответ

1

Вы, вероятно, непонимание как gc.garbage и gc.disable(). gc.disable() отключает циклический сборщик мусора, оставляя активным только управление памятью отсчета. Не существует отдельного «детектора мусора», который продолжает обнаруживать циклический мусор даже тогда, когда сборщик мусора отключен; обнаружение мусора - это работа сборщика мусора.

Кроме того, gc.garbage заполнен только определенными видами странных мусора, которые GC не мог очистить. Большинство мусора никогда не заканчивается там.

Что касается того, как вы собираетесь отлаживать это, я не знаком с инструментами, которые вы будете использовать. Общие инструменты, такие как Valgrind, вероятно, будут полезны, и GC-флаги, такие как gc.DEBUG_LEAK, могут помочь.

+0

Я не согласен. Нециклический мусор собирается даже при вызове 'gc.dissable()'. То, что 'gc.dissable()' does, состоит в том, чтобы остановить сборщик мусора от сбора циклических структур. Неужели я ошибаюсь? Кроме того, я уже использую 'gc.DEBUG_LEAK' - это должно гарантировать, что« обычный »мусор переходит в список« gc.garbage ». Наконец, проблема сохраняется ('gc.garbage' сбой), даже если я не отключу' gc' с 'gc.disable()'. – Krastanov

+1

@ Krastanov: подсчет ссылок по-прежнему активен, но циклическое обнаружение и сбор мусора полностью отключено. – user2357112