﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
36674	select_related() leaks memory	Jacob Walls	nzioker	"Calls to `select_related()` create nested functions that aren't cleaned up until garbage collection runs:

Borrowed testing strategy from #34865:
{{{#!diff
diff --git a/tests/select_related/tests.py b/tests/select_related/tests.py
index 41ed350cf3..252e884d7a 100644
--- a/tests/select_related/tests.py
+++ b/tests/select_related/tests.py
@@ -242,6 +242,30 @@ class SelectRelatedTests(TestCase):
             FETCH_PEERS,
         )
 
+    def test_memory_leak(self):
+        # todo: factor out a test util
+        import gc
+    
+        # Schedule the restore of the garbage collection settings.
+        self.addCleanup(gc.set_debug, 0)
+        self.addCleanup(gc.enable)
+
+        # Disable automatic garbage collection to control when it's triggered,
+        # then run a full collection cycle to ensure `gc.garbage` is empty.
+        gc.disable()
+        gc.collect()
+
+        # The garbage list isn't automatically populated to avoid CPU overhead,
+        # so debugging needs to be enabled to track all unreachable items and
+        # have them stored in `gc.garbage`.
+        gc.set_debug(gc.DEBUG_SAVEALL)
+
+        list(Species.objects.select_related(""genus""))
+
+        # Enforce garbage collection to populate `gc.garbage` for inspection.
+        gc.collect()
+        self.assertEqual(gc.garbage, [])
+
 
 class SelectRelatedValidationTests(SimpleTestCase):
     """"""
}}}

Gives:
{{{#!diff
AssertionError: Lists differ: [<cell at 0x10630c940: function object at [148 chars]040>] != []

First list contains 3 additional elements.
First extra element 0:
<cell at 0x10630c940: function object at 0x1079b8040>

+ []
- [<cell at 0x10630c940: function object at 0x1079b8040>,
-  (<cell at 0x10630c940: function object at 0x1079b8040>,),
-  <function SQLCompiler.get_select.<locals>.get_select_from_parent at 0x1079b8040>]
}}}


At a glance, it looks like we can lift `get_select_from_parent` to a class method or all the way to module-level without a loss of functionality to address this."	Cleanup/optimization	closed	Database layer (models, ORM)	dev	Normal	fixed			Ready for checkin	1	0	0	0	0	0
