possible to leak in-memory data from one ios app to another? - ios

Preface: I'm not an iOS developer and know next to nothing about the iOS security model. So forgive me if this question is truly dumb. :)
Consider an app, called MyApp, that does the following when launched:
Dynamically allocates a chunk of memory, say using malloc().
Loads some sensitive data over the network and stores it in that chunk of memory.
Sits there doing nothing.
Now consider the following scenario:
User launches MyApp.
User closes MyApp.
User launches SomeOtherApp.
My question: If SomeOtherApp also dynamically allocates memory is it possible that one of the buffers returned by the OS will contain the sensitive data placed there by the (now closed) invocation of MyApp?
Or are the contents of RAM treated as part of the sandbox in which an app runs?

Theoretically once the user closes the app (you have to make sure that the app is closed and not just running in the background) the memory that was allocated to that process is deallocated and returned.
To quote from a tutorial on ARC:
"With Automatic Reference Counting enabled, the compiler will automatically insert retain, release and autorelease in the correct places in your program. You no longer have to worry about any of this, because the compiler does it for you."
So when an app closes, all references to any objects which had some sort of memory allocation will be cleared because there will be no objects to reference when the app is not running.
The reason that I say that you have to make sure that it is closed is because some apps, by default, will not close when you press the home button, but will in fact continue to run in the background. This might cause a potential security threat, but unlikely. To ensure that NO memory is still being held on to by that app, make sure that it actually fully closes each time. Make sure that the code is done right and that the person who is writing it, knows and is keeping track of the memory that he allocates.
If security is a big issue, then make sure that all of the memory that does get allocated get properly deallocated in your code. Then make sure that you do an insane amount of testing for memory leaks and whatnot to make sure that no object is left lying with some amount of memory.
I would just like to say that I am not a professional on memory management of even ARC, so it would be best to check with a couple other sources to ensure that my answer is correct.
If I have spoken in err, someone hit me.

Related

Xcode/Swift - Cannot resolve memory issues with Instruments

My application has memory issues where after a certain threshold, the application will crash.
I've been instructed to use Instruments and select the Allocation option.
However, I can never seem to get a "direct" answer to my issue, I have attached screenshots below to help describe the issue better.
The memory issues are not linked to any ViewControllers or files that I have created. Rather other libraries/frameworks which I had no idea were being used. I have been battling this issue for a few weeks, I have altered my code/implemented a variety of methods which I believed may have resolved the issue. However, no luck.
Could someone please tell me how I can combat this issue? As I cannot seem to force the memory to be released which in turn means I have this giant memory bug within my application.
Thank you.
Edit - Added a screenshot of the memory usage when viewing an image at full resolution and returning to the home screen.
A couple of thoughts:
See this answer which talks about using “Debug Memory Graph” tool featured in WWDC 2016 video Visual Debugging with Xcode. That tool is often easier to find issues than Instruments. It organizes the reference counting types by target/framework, making it much easier to sift through the results.
But if you’re dealing with non-reference counted malloced data, then Instruments is the way to go, with all the complexity that entails. But “Debug Memory Graph” is often a better first line of defense.
You said:
The memory issues are not linked to any ViewControllers or files that I have created.
Make absolutely sure that your classes aren’t any buried down there lower in the list. There will be far fewer and the sizes are smaller, so they won’t appear up at the top and they’ll be buried in the list even tho they’re likely to be the root of the problem. Frankly, if your app is running, some of your classes have to be in there somewhere. Lol.
Again, the “Debug Memory Graph” approach helps identify your own objects much more easily than Instruments.
If possible, I’d suggest running the app, returning back to some home screen where you expect stuff to have been released, and repeat that process a few times. The first time you return to a quiescent state is not very illuminating, because there’s going to be a lot of internal caching going on. But the subsequent times you exercise the app and return to that home screen, you’ll have a better example of what’s getting allocated and not released without all of this noise of stuff the OS did on the first iteration:
(Taken from WWDC 2013 Fixing Memory Issues.)
Hopefully, the “warmup” memory isn’t too dramatic, but the red area is what we often focus on, as this is what is “wasted” as we continue to use the app (resulting in eventual crashes).
Unfortunately, your allocations curve isn’t showing it drop at all, which is worrying. Now, maybe you don’t have a “home screen” to which you can return, so maybe this isn’t relevant. But even in that scenario, you should have some state in your app that you can see memory being recovered. It’s hard to say on the basis of the information provided.
You haven’t mentioned it, but confirm what debugging options you have. For example, if you have zombies turned on, you might not see memory drop back as much as it should. Often when we first encounter these sorts of issues, we start flipping on all of these debugging options, but they have an impact on the memory profile of the app. So if you’ve been turning on things like zombies or what have you, you might want to make sure you turn them back off to make sure they’re not part of the behavior you’re seeing.
I’d suggest simulating memory warnings and see if you can see memory being recovered. Make sure your code is observing and responding to memory warnings, purging memory where it can.
This is all general advice and we can’t offer specific counsel without seeing what your code is doing. I’d suggest you create a copy of your project, prune out unrelated stuff, and keep doing that until you have the smallest possible reproducible example of this unbridled memory growth. Often that process will be enough for you to diagnose the problem on your own. But we can’t pour through tons of code. We need a minimal, complete, and verifiable example of the issue.
Bottom line, “Debug Memory Graph” is often our first level of analysis. Run the app, identify what objects you expected to be released but weren’t, and go from there. Also keep an eye on how many of these objects are out there (e.g. if you see the same view controller multiple times, that’s a sign of a strong reference cycle or some circular invocation of view controllers).
Instrument just shows you overview of how your app handling memory/CPU etc. When you find something in instrument, you have to make changes in code.
Refer this: For that you should understand how stong and weak works in iOS.
Once you understand ARC in iOS. You will understand your memory leaks in your code.
Trick is :
Try to check number of objects are not getting removed from memory in instrument.
Then check code for strong reference of object and try to remove unnecessary strong references.
Hope this will help you.
I fixed the issues which I had. Just in case anyone in future experiences the same issues this is what I did:
If declared my outlets/delegates as weak
Wherever I used the keyword self in a block where XCode demanded I use self, I added either [weak self] in or [unowned self] in
Remove any instances of the word self which were not required
Added a deinit and included a print statement
Added a breakpoint where the deinit method is called
Commented out functions in my viewDidLoad method and go through each one to see which one/if one caused the issue.

How to implement didReceiveMemoryWarning in Swift?

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

memory leaks in Corona Apps

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.

iOS : ARC, not freeing memory

I've kind of a weird issue with my iOS app.
after a while my app goes low in memory so memory warning, everything seems to be fine, but when I check the memory usage I noticed that all the calls to viewDidUnload didn't free up lot of memory, so after a few click in my app, it goes again in memory warning, everything seems to be fine again, but not a lot a memory have been released, so it goes again in memory warning faster, and then it crash (after the third memory warning most of the time). this crash is random : app freeze, app leaves, my debugger says app paused, but no bad access or sigbort, no zombies.
my guess is that memory warning can't free up enough memory has it should.
(I checked all my viewDidUnload and make nil every objects that are allocated in viewDidLoad)
Any help will be usefull !
thanks a lot.
So I managed to work with my issue.
I wrote "-(void) dealloc" methode in all my controllers and check if I enter in it as I should. (on pop controller, dissmiss etc..)
Every time it didn't, I do step by step in the controller to see what was retaining my controller from beeing dealloc.
most of the time it was some property that was not in "unsafe_unretained"
delegate that was in "ASSIGN" (and should not be in assign but in unsafe_unretained)
(heritage from non-ARC project...)
I also had some strange controller with XIB that was not deallocated even if empty.
I rebuild new one step by step with copy/paste and finaly with exactly the same code, the new controller was released, with no visible difference between then !!! gnneee
at least I know how to debug that kind issues now...
I don't think there's any way to give a specific answer without more data so the best I can do is suggest that you stop guessing what might be happening with your app and learn how to measure what is actually going on. Run your app under Instruments and you'll be able to check for leaks and also actually see what classes are responsible for the most of your application's memory footprint.
You should make sure you know how to use both the Leaks instrument to identify leaked object but also the Allocations instrument to identify orphaned (but not leaked) sets of objects which should have been released or just cases where your app is not responding to memory warnings as you expected.
https://developer.apple.com/library/ios/#documentation/developertools/conceptual/InstrumentsUserGuide/AboutTracing/AboutTracing.html might be a good place to start and there are a number of tutorials available as well; http://www.raywenderlich.com/2696/how-to-debug-memory-leaks-with-xcode-and-instruments-tutorial and http://www.friday.com/bbum/2010/10/17/when-is-a-leak-not-a-leak-using-heapshot-analysis-to-find-undesirable-memory-growth/ are among the first results I saw.
Vassily,
First, if you aren't yourself releasing extra memory, the the -didReceiveMemory warning does you no good and the OS will keep asking for memory until you are killed. This sounds like it is your problem.
Second, if that isn't the problem then you are probably getting terminated due to the size of your resident memory partitions. Make sure you look at your VM allocation in Instruments. I expect the MALLOC_TINY or MALLOC_SMALL both have greater than 5 MB resident and dirty footprints. Due to the nature of small allocations these VM regions will never shrink. The only option you really have is to not create a lot of small items in the first place. This is really only something you can address by changing you code's algorithms to use less memory.
Andrew

How to detect stuff that has not been released properly

Writing a program for the iphone. Realized that I forgot to release an object, but there was really no indication that the object was not released everything just worked.
What is the best way to track something like this down? Is there a way to see what objects still exist in memory when the program exits out?
Take a look at the Leaks tool in Instruments.
Strictly speaking, when the program exits, it doesn’t matter what you’ve left in memory: the system frees everything that your application allocated throughout its lifetime. Since iOS 4, though, apps usually just get frozen in the background and don’t exit until the system kills them to free up memory. To avoid that—and to reduce your app’s memory footprint, which is important while it’s running—you should, as highlycaffeinated and Daniel suggested, use Instruments’s Leaks tool to check for objects that aren’t getting deallocated properly.
When the app exits, anything in memory is destroyed by the system (not deallocated-- but just outright destroyed when the address space is given back to the system).
While others have suggested using the Leaks tool to find leaks in your app, Leaks won't find many many kinds of memory accretion. If an object is allocated, shoved in a cache somewhere, then the key to that object in the cache is lost, the object is effectively leaked (can never be used again) but won't be find by Leaks because it is still connected to your viable object graph.
A better bet is to use Heapshot analysis to see how your app's object graph grows over time. I wrote up a tutorial on using Heapshot analysis that you might find useful.
If you want to grab a snapshot just before your app exits, then put a sleep(1000); into your code in either an application termination handler or somewhere else that is executed just before the app exits.
Just remember to remove it before shipping a production build. :)
Once an application quits - you don't have access to that. But Instruments (an XCode tool) can look for memory leaks.
Nothing exists in memory when pprogram exits. But you can start with analyzing your code (Product -> Analyze) and running it with (Product -> Profile) Allocations or Leaks in Instruments to find memory management issues.

Resources