Opened 8 years ago

Closed 8 years ago

#14075 closed (wontfix)

ManyToMany relationships create circular references

Reported by: Andrea Corbellini Owned by: nobody
Component: Database layer (models, ORM) Version: 1.2
Severity: Keywords:
Cc: Andrea Corbellini Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no


Here is how you can reproduce the problem:

  1. First, download the attached tar.gz which contains a simple Django project with an app. The important file is, that contains the m2m relationship.
  1. Open a Python console and enable DEBUG_SAVEALL in the GC:
        >>> import gc
        >>> gc.set_debug(gc.DEBUG_SAVEALL)
  2. Import the 'models' module from the Django app:
        >>> from testproj.testapp import models
  3. Run a full collection and check the garbage:
        >>> gc.collect()
        >>> gc.garbage
        [..., <class 'django.db.models.fields.related.Meta'>, ...]

In most of the cases this isn't a problem, because the GC without DEBUG_SAVEALL automatically deletes such objects. However this becomes an issue when you want to disable the garbage collector to increase performances a bit. This problem is caused by the fact that creating a Python's new-style class creates circular references and in fact 'Meta' is a new-style class.

I see that this problem occurs for almost every operation that involves a many-to-many relationships: the Meta class is created (sometimes more than one time) and then is deleted. To avoid the problem, I think that Meta shouldn't be a temporary class, but should be saved somewhere in the model, so that it will never be deleted till the interpreter exits (or the model is destroyed). Using a dictionary instead of a class may solve the problem too.

Attachments (1)

testproj.tar.gz (3.2 KB) - added by Andrea Corbellini 8 years ago.

Download all attachments as: .zip

Change History (4)

Changed 8 years ago by Andrea Corbellini

Attachment: testproj.tar.gz added

comment:1 Changed 8 years ago by Andrea Corbellini

Cc: Andrea Corbellini added

comment:2 Changed 8 years ago by anonymous

Component: UncategorizedDatabase layer (models, ORM)

comment:3 Changed 8 years ago by mariarchi

Resolution: wontfix
Status: newclosed

Pardon me if I wrong, but disabling garbage collector in a language like python seems like a horrible horrible idea to me, because django internals rely on functioning GC. It does not increase performance, it leaks memory.
Python GC uses reference counting and can catch circular references, so it doesn't seem like a problem to me.

Note: See TracTickets for help on using tickets.
Back to Top