#35279: Memory Leak with `prefetch_related`
-----------------------------------------+-----------------------------
Reporter: canton | Owner: nobody
Type: Bug | Status: new
Component: Uncategorized | Version: 4.2
Severity: Normal | Keywords: memory leak
Triage Stage: Unreviewed | Has patch: 0
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
-----------------------------------------+-----------------------------
Memory Leak after calling `queryset.prefetch_related()` or
`prefetch_related_objects()`
To reproduce:
{{{
import gc
from django.db import models
from django.db.models import prefetch_related_objects
class Foo(models.Model):
id = models.AutoField(primary_key=True)
class Bar(models.Model):
id = models.AutoField(primary_key=True)
foo = models.ForeignKey(Foo, on_delete=models.CASCADE)
def prepare_data():
if Foo.objects.exists():
return
foo = Foo()
foo.save()
bar = Bar(foo=foo)
bar.save()
def test1():
# no prefetch
for foo in Foo.objects.all():
for bar in foo.bar_set.all():
print(foo.id, bar.id)
def test2():
# queryset.prefetch_related()
for foo in Foo.objects.prefetch_related("bar_set").all():
for bar in foo.bar_set.all():
print(foo.id, bar.id)
def test3():
# prefetch_related_objects()
foo_list = list(Foo.objects.all())
prefetch_related_objects(foo_list, "bar_set")
for foo in foo_list:
for bar in foo.bar_set.all():
print(foo.id, bar.id)
def run():
prepare_data()
# warn up
test1()
test2()
test3()
gc.collect()
gc.set_debug(gc.DEBUG_LEAK)
gc.collect()
print(f"baseline - garbage count: {len(gc.garbage)}")
test1()
gc.collect()
print(f"test1 - garbage count: {len(gc.garbage)}")
test2()
gc.collect()
print(f"test2 - garbage count: {len(gc.garbage)}")
test3()
gc.collect()
print(f"test3 - garbage count: {len(gc.garbage)}")
gc.set_debug(0)
run()
}}}
Output
{{{
1 1
1 1
1 1
baseline - garbage count: 0
1 1
test1 - garbage count: 0 # no memory leak
1 1
test2 - garbage count: 23 # 23 objects leaked
1 1
test3 - garbage count: 46 # another 23 objects leaked
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/35279>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/0107018e18508607-55fd6223-5289-406d-a678-293bc8f21e1c-000000%40eu-central-1.amazonses.com.