QGraphicsScene::clear() method crashes only in release mode - qt

I inherited my scene from QGraphicsScene. I add many items(QGraphicslineItem, QGraphicsItem, QGraphicsTextItem) on this scene. Whenever i try QGraphicsSceneClear method it crashes on release mode. It works fine on debug mode.
Note: Some items have child items and/or have pointers to other items, so when i delete them i handle them in the destructor (deleting pointers to other items etc). i guess pointers to other items makes it crashing but i do not understand why it crashes only on release mode.
The call stack in release mode is not useful, but it does say access violation on the console.

Your problem is some of your items are deleting other items in the same scene. You have no control (well, not directly) on the order of removal of items when calling clear(). Say you have items A, B, and C. C maintains a pointer to both A and B. When clear() is called, A and B may have already been removed and deleted when C's destructor is called.
As for the crash only happening in release mode, the order of removal may depend on the level of compiler optimization. This is really common when dealing with dangling pointer.

Related

How does operator delete work in qt5 with qObjects

In c++ when u allocate memory, u should always delete them (in Destructors for example). But in qt u often don't worry about deleting objects. Qt does it for u. IDE does not correctly show all the memory leaks. I saw code somewhere like this:
anyLayout->addWidget(new QLabel(QString("text")));
will this QLabel be truly memory leak?
The same question about adding the same way QListString to QComboBox.
No, QWidgets added to a layout will be automatically parented to the layout. This is explained here.
Note: The ownership of item is transferred to the layout, and it's the layout's responsibility to delete it.
When the parents are cleaned up, so will the children. I would encourage you to read about Object Trees & Ownership in Qt.

Update QGraphicsScene from another, non-main thread

I'm pretty new to QT's graphic view frame, and I couldn't find anything about this in the docs or on Google.
I have a GUI application that draws a representation for some data. The application itself does some work with matrices / vectors (a neural net thing) and has to represent it on a QGraphicsScene. So far so good, but I've noticed that the app segfaults & crashes sooner or later (and usually sooner) if I try to update the QGraphicsScene from another thread. The QT Docs say nothing about thread-safety & Google gives nothing. What I want (and pretty much need) to do is run the calculations & update the GUI representation accordingly, but the GUI controls etc themself have to remain responsive. As I said, my first thought was to do the whole thing in another thread, but it crashes randomly if I try to.
Is there any "accepted practice" to do this kind of thing in QT or is there some gotcha that I don't know of in the graphics view framework itself?
The Qt docs actually say quite a lot about thread safety. If the docs for QGraphicsScene don't say anything it's because they are not thread-safe, consistent with the behaviour you are seeing.
What you need to do is run your calculations in another thread and synchronise that thread with the main GUI thread as appropriate. A simple way to do this would be to set a flag in the main thread when the calculations are ready for display. That way you can call the appropriate QGraphicsScene methods in the main thread at the right time by simply checking the flag.

Should non-QObject derived classes "always" be put on the stack?

Coming from the Symbian world, I'm used to using the heap as much as possible to avoid running out of stack space, especially when handling descriptors. CBase derived classes were always dynamically allocated on the heap, since if they were not, their member variables would stay uninitialized. Does the same convention apply to QObject-derived classes?
In Qt it seems to be common to put, for example QString, on the stack. Are the string contents put on the heap while QString acts as a container on the stack, or is everything put on the stack?
As sje397 said: It's idiomatic to put QString and containers on the stack, as they are implicitly shared. Their internals (pimpl idiom "d" pointer) are created on the heap. There is no point in creating the object itself on the heap, too. Just causes memory-management hassles and you lose the intended copy-on-write properties when passing pointers to strings/containers around.
QObjects on the other hand you want to create on the heap in almost all cases, as otherwise they would be destructed again right away. They can't be copied or assigned (well, one can enforce it for own subclasses, but the QObject semantics are broken then), and usually they are supposed to survive the method body they are created in.
Exception is QDialog, which is often created on the stack, followed by QDialog::exec, which blocks until the dialog is closed. But even that is strictly spoken unsafe, as external events (RPC calls, background operations) could cause the dialog to be deleted by its parent (if the parent itself is deleted) before exec returns.
Then having the dialog created on the stack will cause double deletion when unwinding the stack -> crash.
QString, and many other Qt classes, use implicit data sharing. That implies that memory is generally allocated on the heap.

Displaying Flex Object References

I have a bit of a memory leak issue in my Flex application, and the short version of my question is: is there any way (in AcitonScript 3) to find all live references to a given object?
What I have is a number of views with presentation models behind each of them (using Swiz). The views of interest are children of a TabNavigator, so when I close the tab, the view is removed from the stage. When the view is removed from the stage, Swiz sets the model reference in the view to null, as it should. I also removeAllChildren() from the view.
However when profiling the application, when I do this and run a GC, neither the view nor the presentation model are freed (though both set their references to each other to null). One model object used by the view (not a presenter, though) IS freed, so it's not completely broken.
I've only just started profiling today (firmly believing in not optimising too early), so I imagine there's some kind of reference floating around somewhere, but I can't see where, and what would be super helpful would be the ability to debug and see a list of objects that reference the target object. Is this at all possible, and if not natively, is there some light-weight way to code this into future apps for debugging purposes?
Cheers.
Assuming you are using Flex Builder, you could try the Profiler. In my experience, it's not so good for profiling performance, but it's been of great help for finding memory leaks.
It's not the most intuitive tool and it takes a while to get used to it (I mean, to the point where it actually becomes helpful). But, in my opinion, investing some time to at least learn the basics pays off. There's an enormous difference between just seeing how much memory the player is using globally (what System.totalMemory gives you, a very rough, imprecise and often misleading indicator) and actually track how many instances of each object have been created, how many are still alive and where were they allocated (so you can find the potential leak in the code and actually fix it instead of relying in black magic).
I don't know of any good tutorials for the FB profiler, but maybe this'll help to get you started.
First, launch the profiler. Uncheck performance profiling and check everything else (Enable memory profiling, watch live memory data and generate object allocation stack traces).
When the profiler starts, you'll see stats about the app objects, grouped by class. At this point, you might want to tweak filters. You'll see a lot of data and it's very easy to be overwhelmed. For now, ignore everything native to flash and flex stuff, if possible, and concentrate on some object that you think it should be collected.
The most important figures are "cumulative instances" and "instances". The first is the total number of instances created so far; the second, the number of said instances that are still alive. So, a good starting point is get your app to the state where the view you suspect that leaks gets created. You should see 1 for "cumulative instances" and "instances".
Now, do whatever you need to do to get to the point where this view should be cleaned up (navigate to other part of the app, etc) and run a GC (there's a button for that in the profiler UI). A crucial point is that you will be checking the app behaviour against your expectations -if that makes sense-. Finding leaks automatically in a garbarge collected environment is close to impossible by definition; otherwise, there would be no leaks. So, keep that in mind: you test against your expectations; you are the one who knows the life cycle of your objects and can say, "at this point this object should have been collected; if it's not, there's something wrong".
Now, if the "instances" count for you view goes down to 0, there's no leak there. If you think the app leaks, try to find other objects that might not have been disposed properly. If the count remains at 1, it means your view is leaked. Now, you'll have to find why and where.
At this point, you should take a "memory snapshot" (the button next to the Force GC button). Open the snapshot, find the object in the grid and double click on it. This will give you a list of all the objects that have a reference to this object. It's actually a tree, and probably each item will contain in turn a number of backreferences and so on. These are the objects that are preventing your view from being collected. In the right panel, also, you will an allocation trace. This will show how the selected object was created (pretty much like a stack trace).
You'll probably see a hugh number of objects there. But your best bet is to concentrate in those that have a longer life cycle than the object you're examining (your view). What I mean is, look for stage, a parent view, etc; objects on which your view depends on rather than objets that depend on your view, if that makes sense. If your view has a button and you added a listener to it, your button will have a ref to your view. In most cases, this is not a problem, since the button depends on the view and once the view is collect, so is the button. So, the idea is that since there are a lot of objects, you should try to stay focused or you will get nowhere. This method is rather heuristic, but in my experience, it works.
Once you find the source of a leak, go back to the source, change the code accordingly (maybe this requires not just changing code but refactoring a bit). Then repeat the process and check whether your change has caused the desired effect. It might take a while, depending on how big or complex is your app and how much you know about it. But if you go step by step, finding and fixing one problem at the time, you'll eventually get rid of the leaks. Or at least the worst and more evident ones. So, while a bit tedious, it pays off (and as a nice aside, you'll eventually understand what a waste of time is in most cases to use weak refs for every single event handler on the face of this earth, nulling out every single variable, etc, etc; it's an enlightening experience ;).
Hope this helps.
Flash GC uses a mix of ref counting and mark and sweep, so it does detect circular references. It seems rather you're having another reference in you object graph. The most common reason is, that the objects you want disposed still are having event handlers registered on objects that are not disposed. You could try to ensure that handlers are always registered with weak reference. You could also override addEventListener and removeEventListener in all (base) classes, if possible, to look which listeners are registered and whether there are chances for some not to be removed.
Also, you can write destructors for your objects, that for ui components clear graphics and remove all children, and for all objects, removes references to all properties. That way, only your object is kept in RAM, which shouldn't require much memory (a small footprint of 20 B or so, plus 4 B per variable (8 for a Number)).
greetz
back2dos
also a useful heuristics for finding memory leaks: http://www.tikalk.com/flex/solving-memory-leaks-using-flash-builder-4-profiler

Force Garbage Collection in AS3?

Is it possible to programmatically force a full garbage collection run in ActionScript 3.0?
Let's say I've created a bunch of Display objects with eventListeners and some of the DO's have been removed, some of the eventListeners have been triggered and removed etc... Is there a way to force garbage collection to run and collect everything that is available to be collected?
Yes, it's possible, but it is generally a bad idea. The GC should have a better idea of when is a good time to run than you should, and except for a very specific case, like you just used 500MB of memory and you need to get it back ASAP, you shouldn't call the GC yourself.
In Flash 10, there is a System.gc() method you can call (but please don't, see above) - keep in mind System.gc() only works in the debugging version of Flash player 10+.
In Flash 9, there is an unsupported way to force it via an odd LocalConnection command, but it may not work in all versions. See this post by Grant Skinner.
There is a new API for telling the GC that it might be a "relatively good moment" to collect.
See the Adobe API docs for
System.pauseForGCIfCollectionImminent
And also this Adobe blog post from shortly after the method was introduced in Player version 11
The method takes an "imminence" argument; basically, you feed in a low number (near 0.0) if you really want the collector to run, even if there has not been much activity (currently measured by bytes-allocated) since the last collection, and you feed in a large number (near 1.0) if you only want the collection pause to happen if we were already near the point where a collection would happen anyway.
The motivation here is for situations in e.g. games where you want to shift the point where GC's happen by a small amount, e.g. do the GC during a change of level in the game, rather than two seconds after the player started exploring the level.
One very important detail: This new API is supported by both the Release and the Debugger Flash Runtimes. This makes it superior to calling System.gc().
For all currently released versions, System.gc() only works in the debug version of the Flash player and ADL (the debug environment for AIR apps). Flash player 10 beta currently does work in all flavors.
I agree with Davr, it's a bad idea to do. The runtime will usually have a better idea than you do.
Plus, the specifics of how the garbage collector works is an implementation detail subject to change between flash player versions. So what works well today has no guarantee to work well in the future.
As others said: do not try to GC manually, there are hacks but it's not safe.
You should try recycling objects when you can - you'll save a lot of memory.
This can be applied for instance to BitmapDatas (clear and reuse), particles (remove from display and reuse).
I have a comment on those saying you should never do GC manually. I'm used to manual memory management in C++ and I prefer sharedptr a lot over GC, but anyway.
There is a specific case where I can't find another solution than do a GC. Please consider: I have a DataCache class, the way it work is it keeps result objects for certain method calls that send out updated events when refreshing/receiving data. The way the cache is refreshed is I just clean all results from it and send the event which causes any remaining listeners to re-request their data and listeners that went out of scope should not rerequest which cleans out not needed results. But apparently, if I can't force all listeners that still dangle waiting for GC to be cleaned up immediatly before sending out the "ask you data again" event, those dangling listeners will request data again unnecessarily. So since I can't removeEventListener because AS3 doesn't have destructors I can't see another easy solution than forcing a GC to make sure there's no dangling listeners anymore.
(Edit) On top of that I cannot use removeEventListener anyway for binding which were setup in mxml, for example (using my custom DataCacher class which handles remoteobj)
<mx:DataGrid id="mygrid" dataProvider="{DataCacher.instance().result('method').data}" ... />
When the popup window containing this datagrid is closed, you would expect the bindings to be destroyed. Apparently they live on and on. Hmm, shouldn't flex destroy all bindings (meaning eventlisteners) from an object when it's being marked for GC because the last reference is deleted. That would kinda solve the problem for me.
At least that's why I think, I'm still a beginner in Flex so any thoughts would be appreciated.
try {
new LocalConnection().connect('foo');
new LocalConnection().connect('foo');
} catch (e:*){
trace("Forcing Garbage Collection :"+e.toString());
}
If you have to, calling the gargabe collector could be useful... so, you have to be carefull how and when you do it, but there is no doubt that there are times when is neccesary.
for example, if you have an app that is modular, when you change from one view to the other, all the deleted objects could represent a large amount of memory that should be available as faster as possible, you just need to have control of the variables and references you are disposing.
recycling doesn't really help. I used one loader that repeatedly loaded the same jpg every 500ms. task manager still reported a non stop increase in memory.
tried and proven solution here.
http://simplistika.com/as3-garbage-collection/

Resources