Opened 5 years ago

Closed 4 years ago

#14075 closed (wontfix)

ManyToMany relationships create circular references

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

Description

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 models.py, 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()
        6
        >>> 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 candrea 5 years ago.

Download all attachments as: .zip

Change History (4)

Changed 5 years ago by candrea

comment:1 Changed 5 years ago by candrea

  • Cc candrea added
  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset

comment:2 Changed 5 years ago by anonymous

  • Component changed from Uncategorized to Database layer (models, ORM)

comment:3 Changed 4 years ago by mariarchi

  • Resolution set to wontfix
  • Status changed from new to closed

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