Replies: 9 comments 29 replies
-
If your GC run often, so there're something are eating your RAM run often in your app. You need to optimize your code. You need to proactively destroy your objects when you doesn't need it anymore. Call gc when you close a tab, a dialog... Furthermore, almost all of your classes should be "destroyable". In a framework that I'm building, I have DestroyableTextField, DestroyableContainer, DestroyableDispatcher... that implement IDestroyable. And I have a method called And don't forget to publish your app in release mode. |
Beta Was this translation helpful? Give feedback.
-
The pause due to GC would tend to be the "collection" phase i.e. destroying all the objects that have no valid references left and cleaning up their memory. This can trigger destructors too (less of a thing in AS3, but it does happen under the hood in C++). And it's all done at once, single-threaded, hence the potential pause in the runtime if there is a lot to do there. So per @ylazy's comments, the best things to do here would be to ensure it has less to do, when it does this! The two options really are:
Of course, you can also improve things by not actually getting rid of objects - so e.g. object caching, if you know you'll need to use objects of the same type again in the future. If you have two objects that reference each other, then they won't ever get collected by this reference-count mechanism. This is where we end up having to do the 'slow' garbage collection, where we gradually go through all the objects from the root and mark them as being "used". Then once that phase has finished (little and often, i.e. incremental marking) we get to the phase where we collect all the objects that were not marked as "used" and this is where you see the pause. This is also where Scout can be useful, if you look at the allocations and deallocations between some of your frames, you can see how many of each type of object are being created vs destroyed, which gives an indication of what bits of code to look at to see if they can be refactored so that you don't end up with hanging references or just relying on this mark-and-sweep form of garbage collection.. Your final question - "run it in the background" - I'm not actually completely sure why the collection is done all at once, whilst the marking can be done incrementally. I suspect it's related to the fact that these objects may reference each other and we don't want to have such references hanging around whilst we're halfway through some of the destructor calls. But we can check that.. |
Beta Was this translation helpful? Give feedback.
-
@ajwfrost We have been using scout to detect bottlenecks, but our app is data intensive. Objects get created and destroyed, and we accept we don't have the best object pool management. But let's take this code for example:
Here the GC was "caused" by The huge delay we are seeing could potentially be worsen by the fact that we have thousands of data objects in memory. A quick test reveled that if we generate 10k It's even worse in our app, having moments with 0.7 fps and 90% caused by GC. Probably because of a more complex reference tree. Since event the code above adds to the problem, and all the
We are trying to optimize as much as possible, we moved data from memory to DB, and DB had some issues too, and we are moving some back to memory / cache. We have created a spaghetti monster, but GC is still our biggest enemy. Code I used for testing:
|
Beta Was this translation helpful? Give feedback.
-
Why did you do that? This code did nothing. If you want to remove all items of memoryTemp from memory, use: memoryTemp.length = 0; this code is better: var now:Date = new Date();
var memoryTemp:Array = [];
var d:Date;
var i:uint;
this.addEventListener(Event.ENTER_FRAME, function (e:Event):void
{
for (i = 0; i < 10000; ++i)
{
d = new Date();
d.time = now.time;
memoryTemp[i] = d;
now.time --;
}
}); It runs at 60 FPS on my machine in release mode. |
Beta Was this translation helpful? Give feedback.
-
@ajwfrost anything that it is clearly done wrong here? |
Beta Was this translation helpful? Give feedback.
-
@ajwfrost we are more than happy to help with whatever you can throw at us to test or whatever! This might actually help overall performance of air quite a bit :) |
Beta Was this translation helpful? Give feedback.
-
Is the Array maybe getting resized/reallocated sometimes during push() and pop()? |
Beta Was this translation helpful? Give feedback.
-
Semi-Offtopic, @ajwfrost, I was wondering, if we could get a specific method to manually dispose/destroy an object directly/immediately rather than making sure it will get garbage collected by nulling references etc? Not sure if applicable though... |
Beta Was this translation helpful? Give feedback.
-
@ajwfrost should we expect any improvement here? Just trying to get some sort of a conclusion. |
Beta Was this translation helpful? Give feedback.
-
Hey @ajwfrost,
Our interface freezez now and then and it is super annoying. (tested on a windows app)
Upon some Scout investigation, we noticed that the issue arrises when GC decies to come in and just kills the processing time with huge spikes.
Is there any way to avoid this? Make it run less often? Or any other parameters we can use it with? Run it in background? :)
Thanks.
Beta Was this translation helpful? Give feedback.
All reactions