[Development] [QML] Singletons are deleted before the other objects
Simon Hausmann
simon.hausmann at digia.com
Thu Sep 25 07:34:28 CEST 2014
On Monday, September 22, 2014 02:28:06 AM BogDan wrote:
> ----- Original Message -----
> From: Simon Hausmann <simon.hausmann at digia.com>
> To: BogDan <bog_dan_ro at yahoo.com>
> Cc: Chris Adams <chris.adams at qinetic.com.au>; Qt Development Group
> <development at qt-project.org> Sent: Monday, September 22, 2014 11:56 AM
> Subject: Re: SV: [Development] [QML] Singletons are deleted before the
> other objects
> On Monday 22. September 2014 01.33.14 BogDan wrote:
> > On Monday 22. September 2014 01.19.17 BogDan wrote:
> > > Hi Simon,
> > >
> > > I took a look and I'm pretty sure I'm right ;-). BTW I'm using 5.4
> > > branch (sha1 f9ee33f96), is a little bit old, but I bet nobody
> > > fixed it. The same problem is in previous releases.
> > >
> > > So, the singletons are deleted in QQmlEngine::~QQmlEngine():910
> > > The other active objects are deleted in MemoryManager::sweep(*true*)
> > > which is called by MemoryManager::~MemoryManager()
> > > which is called by ExecutionEngine::~ExecutionEngine()
> > > which is called by QV8Engine::~QV8Engine()
> > > which is called by QJSEngine::~QJSEngine()
> > > which is called *after* QQmlEngine::~QQmlEngine()
> > >
> > > Check the call-stack:
> > > 0 MyObject::~MyObject myobject.cpp 44 0x7fffd141eb4b
> > > 1 MyObject::~MyObject myobject.cpp 46 0x7fffd141ec8a
> > > 2 (anonymous namespace)::QObjectDeleter::~QObjectDeleter
> > > qv4qobjectwrapper.cpp 1018 0x7ffff5f79ee1 f9ee33f96f9ee33f96 3
> > > (anonymous namespace)::QObjectDeleter::~QObjectDeleter
> > > qv4qobjectwrapper.cpp 1021 0x7ffff5f79f2e 4
> > > QV4::MemoryManager::sweep qv4mm.cpp 377 0x7ffff5efd080
> > > 5 QV4::MemoryManager::~MemoryManager qv4mm.cpp 515 0x7ffff5efda18
> > > 6 QV4::ExecutionEngine::~ExecutionEngine qv4engine.cpp 421
> > > 0x7ffff5ee4f54 7 QV8Engine::~QV8Engine qv8engine.cpp 116
> > > 0x7ffff606b7f2
> > > 8 QV8Engine::~QV8Engine qv8engine.cpp 117 0x7ffff606b87e
> > > 9 QJSEngine::~QJSEngine qjsengine.cpp 203 0x7ffff5e64b1e
> > > 10 QQmlEngine::~QQmlEngine qqmlengine.cpp 893 0x7ffff5fb0b5d
> > > 11 QQmlEngine::~QQmlEngine qqmlengine.cpp 916 0x7ffff5fb0b8c
> > > 12 QObjectPrivate::deleteChildren qobject.cpp 1943 0x7ffff599efd0
> > > 13 QObject::~QObject qobject.cpp 1034 0x7ffff599d760
> > > 14 QWindow::~QWindow qwindow.cpp 210 0x7ffff63f5bdc
> > > 15 QQuickWindow::~QQuickWindow qquickwindow.cpp 1099
> > > 0x7ffff6bc0353
> > > 16 QQuickView::~QQuickView qquickview.cpp 220 0x7ffff6c9fe35
> > > 17 main main.cpp 12 0x4021fb
> > >
> > > IMHO the sequence from QQmlEngine::~QQmlEngine():910 should be moved
> > > after/in MemoryManager::~MemoryManager ...
> >
> > Ahh, so what you're talking about are the _JavaScript_ wrappers for the
> > singletons, not the singleton objects themselves. That explains the
> > confusion.
> >
> > Yes, due to the inheritance the final garbage collection runs as the very
> > last step - and it has to, conceptually. I'm wondering: What code do you
> > have running at that point that gets still called? Is it code in C++
> > destructors?
> >
> >
> >
> >
> >
> >
> > Yes, the code from their destructors needs the singletons objects which
> > are
> > not available anymore.
>
> When are those destructors called?
>
> We need a little bit more information here, because it isn't obvious how to
> solve this. There's naturally a pool of objects around that haven't been
> garbage collected. On engine shutdown the garbage collector sweeps them all,
> and there's naturally no way to define an order of destruction if you think
> of such an environment.
>
>
>
>
>
> I know that there is a pool of active objects, what I think is wrong is to
> delete the register singletons before you delete these objects.
>
>
> The active objects destructors are called by MemoryManager::sweep.
> These objects register themselves in the singleton object when they are
> created and they must unregister themselves in the destructor when they
> are deleted. But as you seen the singletons are deleted before, so there is
> no way to properly unregister themselves! This is why I believe that the
> singletons must be the very last objects that are deleted (just like in
> any other languages).
>
> So, my proposal is to move the singletons deletion from
> QmlEngine::~QQmlEngine():910 to another place which is called after
> MemoryManager::sweep(*true*) is doing its job.
>
> I'd like to mention one more thing, the singletons and the other objects
> are register in a standalone plugin.
>
> Please let me know if you need more info.
I think I see what you mean now. The main issue I have with this is that it
would break singletons written in QML. Just like C++ they may also have
their Component.onDestruction handlers, and those would naturally not be
callable anymore after such a move. Not calling those anymore would be a
change in behavior.
I'm not convinced that this is a change for the better TBH. Of course we could
try to delete first the QML singletons, then the rest of the JavaScript world
and then finally the C++ singletons. But you have to admit, that starting to
feel like a bunch of hacks.
Instead of relying on an order of destruction, why not reference your C++
object with a weak pointer?
Simon
More information about the Development
mailing list