Message360995
The new Pickler reducer_override mechanism introduced in `Python3.8` generates a reference cycle: for optimization purposes, a the pickler.reducer_override bound method is referenced into the reducer_override attribute of the Pickler's struct. Thus, until as a gc.collect call is performed, both the Pickler and all the elements it pickled (as they are part of its memo), wont be collected.
We should break this cycle a the end of the dump() method.
See reproducer below:
```
import threading
import weakref
import pickle
import io
class MyClass:
pass
my_object = MyClass()
collect = threading.Event()
_ = weakref.ref(my_object, lambda obj: collect.set()) # noqa
class MyPickler(pickle.Pickler):
def reducer_override(self, obj):
return NotImplemented
my_pickler = MyPickler(io.BytesIO())
my_pickler.dump(my_object)
del my_object
del my_pickler
# import gc
# gc.collect()
for i in range(5):
collected = collect.wait(timeout=0.1)
if collected:
print('my_object was successfully collected')
break
``` |
|
Date |
User |
Action |
Args |
2020-01-29 23:39:28 | pierreglaser | set | recipients:
+ pierreglaser, pitrou |
2020-01-29 23:39:28 | pierreglaser | set | messageid: <1580341168.06.0.481762102037.issue39492@roundup.psfhosted.org> |
2020-01-29 23:39:27 | pierreglaser | link | issue39492 messages |
2020-01-29 23:39:27 | pierreglaser | create | |
|