I have released all the display objects and my every scene got destroyed after executing. I have multiple screens in app and I am using storyboard for transactions. When I made transaction from one to another very slightly memory usage increased, but if I run my app for a long time , it starts hanging and sometimes respond very slowly.
Does this happen to you running the storyboard sample? If so, you should file a bug report and consider using Director as an alternative in the meantime. If not you should carefully review your code to ensure you are properly disposing of sprite sheets, audio, etc. and that you aren't using globals.
Related
I’m currently working on a tvOS app. This is my first native (Swift) app. The app will be a digital signage app, used during events or in offices of companies.
One big difference compared to a typical app on iOS/tvOS is that it needs to run pretty much 24/7, so memory is a big topic for this app. The smallest leak will eventually cause the app to crash.
The app is constantly looping through a set of fullscreen slides. At the bottom of the screen there is a ticker with 10 articles (refreshed every 10 seconds - now during development). Below is a screenshot of the weather slide, to get an idea.

Currently the app is crashing after a period of time and I’m pretty sure I’ve narrowed it down to the ticker component (when disabling it, the app lives for days). If I use the ‘Leaks’ preset in Instruments I get the following result:

It looks like it’s leaking Article instances. I’m recreating Article instances every 10 seconds and providing them to the ticker component. I think that is why new instances leak every ~10 seconds.
Before I started using the ‘Leaks’ preset in Instruments, I used the ‘Allocations’ preset, while using this all seemed fine to me. But I’m probably misreading the results…
Using allocations:

The way I read this is that currently 10 Article instances exist in memory, and 31 have existed but are cleaned up now - so I’m safe.
But the app still crashes.
I’ve read a lot on retain cycles, implemented weak/unowned where I believe I should.
So my question is not so much about code, but more about how to read this data, what does a Leak mean in this context, and why do I see these ‘leaks’ not as persistent objects in the Allocations window?
(tests are done on multiple devices + simulator)
If you see a steady (i.e., approximately n GB / minute or hour) increase in memory usage in Instruments, that is a good sign that objects are being created, but not dealloced. Your allusion to weak and unowned vars makes me think that you know this, but you may not have found all sources of your leak. I would suggest taking a few generation summaries in Instruments, and looking at specific classes/objects in Heap allocations. Your problem classes will steadily increase in number, and likely never decrease. Try to debug the problem from there.
As for what 'leak' means in this context, it's what it always means: Your computer is not releasing memory resources. It may seem different, because we are used to thinking of a leak as something that eats through memory at a much faster rate (like an infinite loop running on four cores, or something), but that kind of leak and this are actually the same thing; yours is just slower.
I’m back after weeks trying to figure out what was wrong. The good news, I found my leak, and solved it!
The issue was solved by removing a closure inside another closure keeping a reference to a variable in the first closure. This caused a retain cycle.
I really don’t understand why I didn’t find it earlier, I asked a new question for this here: getting-different-data-in-instruments-based-on-method-of-profiling.
Whenever I create a new View Controller subclass, Xcode automatically adds the method
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated
}
Usually I just delete it or ignore it. This is what all the tutorials I have seen do, too. But I assume that since Xcode gives it to me every time, it should be somewhat important, right? What should I be doing here? I assume that disposing of resources means setting them to nil, but what exactly are "resources that can be recreated"?
I have seen these questions:
How to implement didReceiveMemoryWarning?
UIViewController's didReceiveMemoryWarning in ARC environment
iPhone Development - Simulate Memory Warning
But they are all pre-Swift. Although I don't know much about Objective-C, I have heard that the memory management is different. How does that affect what I should do in didReceiveMemoryWarning?
Other notes:
I am fuzzily aware of Automatic Reference Counting and lazy instantiation
The documentation on didReceiveMemoryWarning that I found was rather brief.
Swift
Swift uses ARC just like Objective-C does (source to Apple Docs). The same kind of rules apply for freeing memory, remove all of the references to an object and it will be deallocated.
How to free memory
I assume that disposing of resources means setting them to nil, but what exactly are "resources that can be recreated"?
"resources that can be recreated" really depends on your application.
Examples
Say you are a social media app that deals with a lot of pictures. You want a snappy user interface so you cache the next 20 pictures in memory to make scrolling fast. Those images are always saved on the local file system.
Images can take up a lot of memory
You don't need those images in memory. If the app is low on memory, taking an extra second to load the image from a file is fine.
You could entirely dump the image cache when you receive that memory warning.
This will free up memory that the system needs
You are creating an amazing game that has a number of different levels.
Loading a level into your fancy game engine takes a while so if the user has enough memory you can load level 3 while they are playing level 2.
Levels take up a lot of memory
You don't NEED the next level in memory. They are nice to have but not essential.
LevelCache.sharedCache().nextLevel = nil frees up all that memory
What shouldn't you deallocate
Never deallocate the stuff that is on screen. I've seen some answers to related questions deallocate the view of the UIViewController. If you remove everything from the screen you might at well crash (in my opinion).
Examples
If the user has a document open that they are editing, DON'T deallocate it. Users will get exceptional angry at you if your app deletes their work without ever being saved. (In fact, you should probably have some emergency save mechanism for when that happens)
If your user is writing a post for your fabulous social media app, don't let their work go to waste. Save it and try to restore it when they open the app again. Although it's a lot of work to setup I love apps that do this.
Note
Most modern devices rarely run out of memory. The system does a pretty good job of killing apps in the background to free up memory for the app running in the foreground.
You have probably seen an app "open" in the App Switcher yet when you tapped on the app it opened to its initial state. The OS killed the app in the background to free up memory. See State Restoration for info on how to avoid this problem.
If your app is getting consistent memory warnings when you aren't doing a huge amount of processing make sure that you aren't leaking memory first.
Detecting memory leaks is outside the scope of this answer. Docs and a tutorial.
When didReceiveMemoryWarning is called, it means your app is using too much memory (compare with memory of device), and you should release any additional memory used by your view controller to reduce the memory of your app. If the memory app gets over the memory of device, iOS will kill your app immediately. "resources that can be recreated" means somethings you can recreate it again at somewhere, you don't need them now (don't need to put them in the memory). And you can release it when get didReceiveMemoryWarning.
Here is another detail topic: ios app maximum memory budget
Nearing the end of my first (very simple) game using spritekit.
I have noted a long delay (about 10 -13 seconds) when running the app on a real device at start up.
I am assuming this is the time taken to load resources and execute code in initWithSize().
Is there a workaround or what is the recommend approach i.e. use a splash screen while game loads.
I am using a texture atlas but my understanding is that is for optimising resource calls during runtime.
Cheers
Using the instruments tool can help you locate where bottlenecks appear in code. I doubt it is 10-13 seconds from app launch as any app that takes 10 seconds or longer to launch is killed by the system.
Try to load resources intelligently. Load what is absolutely necessary when launching for what I assume would be your menu. If there are variations in different gameplay roles or similar assets used across multiple levels. Load them up, then when a selection has been made load anymore initial resources.
Also try to recycle resources where possible. For instance if an enemy is destroyed by the player. Don't destroy the object. Reuse it, the memory space it took up is likely to be the same again and creation is more expensive than reusing.
I found a lot of brilliant pointers in using Profiling tools through the WWDC talks, they are always a great resource.
So I just made an app that loads a map with some markers on it. The app has a navigation controller that segue from the main screen to the map and back. While running the app on my phone and simulator i noticed that if i went back and forth between the home screen and the map, the amount of memory that the app was using just kept growing indefinitely. Is there way to assist in the process of memory management (i know the system uses ARC)? Im using the google maps sdk btw.
Thanks!
Does it cause the app to run out of memory and crash?
Or is it using a ton of memory, receiving a memory warning, and dumping said memory?
So, unless it is causing crashes, it may be behaving correctly.
Apple has extensive and well-documented support for diagnosing these kinds of problems. See "Locating Memory Issues in Your App".
Check your codes where using NSThreads and GCD blocks. If there are some places you create plenty of threads, it is recommended to add a autoreleasepool block.
Memory may leak in these situation:
If you are writing a program that is not based on a UI framework, such as a command-line tool.
If you write a loop that creates many temporary objects.
If you spawn a secondary thread.
For reference: Using Autorelease Pool Blocks
short question: someone (cit. 5) told me that resident memory could be reclaimed by my system. What does this mean? Does it mean that my App is not using that memory or is the resident memory value directly related to the memory being currently used by my App? I haven't found much documentation on this apart from those answers.
I am trying to solve an issue. I am writing a game usign iOS 6.0 and Cocos2d 2.0 and I do get some memory problems. I have Cococs2d 2.0 as static library and I wrote my code using ARC (which I suspect being the reason).
Going from Initial scene to Character Selection Scene and then to Planet Selection scene and finally Game scene I observe that the resident_size of memory increases.
I added this code at each scene init and I tracked down the values. The following picture show the user experience path I do. On the left colum there are the scene names, on the second colum the amount of memory used in the normal flow (not going back to the previous scene) and in the third block of colums there are the values of resident memory going back and forwards from specific scenes.
As we can observe the Main scene presents an issue probably different from the other scenes. Every time I load the scene I get a memory increase of about 15 MB.
I run an indipendent test on the scene (using a reload callback method) and I get the following values:
Interestingly, running the same test on the CharacterSelection Scene does not have a progressive increase of memory after the third load (stays 37MB). However I do not understand why initially goes from 27 MB to 32 MB and NOT to 37MB (or, I should say, I do not understand why it goes from 32 MB to 37 MB).
I run another set of test trying to parse from one scene to the other and I do get interesting results. Here is the schema:
**Someone answered to me saying "Resident memory is a measurement of the memory that has been allocated to your application and has not yet been reclaimed by the system, but some/most of the resident memory could be reclaimed by the system."
Does this mean that resident memory values are not necessarily memory used by my App?
According to my test, there does seem to be a correlation between scenes and their memory used and resident memory value.
So if this is correct I should keep trying to solve this issue as the higher the resident memory value is the more likely my APP is to be killed. If, instead the memory would be available to the system to be used then there would be no crash. Given that there are crashes I assume that the memory is somehow leaked. However the leak tool does not detect any leaks (is this because I am using XCode 4.5?).
Any help? Is this related to using ARC?
The issue was that I was measuring the memory during the init method of the new scene. The report was hence including the assets of the previous scene (as it was not yet being deallocated).
Adding a callback with a 0.1 delay solved it and answering my questions:
Q:
someone (cit. 5) told me that resident memory could be reclaimed by my
system. What does this mean? Does it mean that my App is not using
that memory or is the resident memory value directly related to the
memory being currently used by my App?
A:
it is the memory directly related to the memory being used by my App. Using a delay in the callback of this function plus a call to [[CCTextureCache sharedTextureCache] dumpCachedTextureInfo]; will confirm this.
Q:
Any help? Is this related to using ARC?
A:
Not in this case fortunately. There where other issues causing leaks in some scenes. For example, the starting scene was subclass of another scene. This starting scene had some child nodes being added as child which where not being removed on the cleanup method of the scene. Adding an explicit removal of those child nodes solved the issue. I am not sure why this was necessary (I was expecting all child nodes to be automatically removed) but it solved the issue.