I am working on Xcode8 and Swift3. While running the app I am using visual memory debugging. It shows me 3 memory issues on left hand side. Please let me know how can I resolve these memory issues?
Well, it's really hard to tell you how to solve those issues without knowing the flow of your program. Plus, there are a lot of causes to memory issues, and it really depends on how you handled the instances of your object.
If you are not using ARC, the it means that you are responsible for releasing any object you created. Then you have to check in which stage did that object get leaked. As it stated there, it is a Dictionary that got leaked. So you have a clue on what specific object to check.
On the other hand, if you are using ARC, then you don't have to handle releasing of the objects that you created. But, it doesn't mean that you won't get any leaks. These are some possible causes that may cause a memory leak in your program even if using ARC:
You set a strong reference to a parent in a child object. This causes a retain cycle.
You set a strong reference to a delegate in an interface.
You forgot to release an object when you do a toll-free bridging after transferring ownership.
You forgot to set a weak reference to objects you passed in a block.
I hope this helps
Related
As I start working in swift, I am curious in memory mgmt. As we all know that during any object creation or assignment of data into that object it takes memory. How can we check that a particular object has released the memory. I used xcode memory report to see memory status and fluctuations.
Here is a sample of images:
How can release memory if I already set nil into the objects.
Use instruments to track the lifecycle of an object than just Xcode because it gives you the allocation details at much higher level.
Check out the answer at https://stackoverflow.com/a/14891837/5133769. Though it was explained with old instruments it still works.
Some objects are very small and it could be difficult to see in Memory profiling which one is released. This tool is helpful for finding memory leaks in an app. To check was some object released from memory or wasn't you can setup breakpoints or logs in dealloc() method for objective c and in deinit() method for swift.
Using instruments checking for leaks or allocations is the recommended way.
You can also set breakpoints or add logs to the dealloc method.
As I learnt from the apple documentation that ,In iOS ARC will automatically take care of the memory leaks and memory management.
But my doubt was, do we still need the role of Xcode instruments (Allocations and Leak) to ensure whether memory leak has happened in our application??
Please do share if you know the solution.
Yes, of course you need to use Intruments.
Swift uses Automatic Reference Counting (ARC) to track and manage your app’s memory usage. In most cases, this means that memory management “just works” in Swift, and you do not need to think about memory management yourself. ARC automatically frees up the memory used by class instances when those instances are no longer needed.
However, in a few cases ARC requires more information about the relationships between parts of your code in order to manage memory for you. This chapter describes those situations and shows how you enable ARC to manage all of your app’s memory.
You should take a look over Automated Reference Counting.
One of the most common situation is when you have strong reference cycles between class instances, because the compiler doesn't know when to release that part of memory. Also take a look over the differences of strong and weak references.
But as even Apple saids, "In most cases", you should be ok without, but if your application crashes, it could be that you have memory issues.
Automated reference counting provides a new, simpler, way of managing reference counted objects. By automating the tasks of calling retain and release it eliminates a large class of memory leaks and invalid references caused by programmers forgetting to call memory management functions.
However, ARC does not eliminate a different class of leaks caused by logical errors in the design of your code, when your object graph has cycles. ARC provides tools for you to address this issue by adding weak references, but if you don't do it right, there is nothing ARC can do to help you.
In addition, you may have "lingering references", when an object remains in memory even though your program no longer needs it. Memory leaks of this kind can happen even in garbage-collected environments, such as Java and C#. They represent a logical error in design, and cannot be eliminated by clever compiler tricks in the current state of compiler technology.
This is when Xcode memory tools come in handy. You run them to check for memory leaks, ensuring that your code does not have cycles and "lingering references".
I may have an incomplete understanding of using allocations in instruments. I am trying to debug a retain cycle. At key points in my app I use 'Mark Generation' .
I am looking for a subclass of a UIViewController that never has it's dealloc method called when it goes out of scope. Checking the generation data under generations shows a lot of stuff but no Objects that were allocated during execution.. in fact there is nothing that I recognise from my code in here, no UI objects whatsoever. Perhaps I have missed a setting that records these things somewhere?
I know that the biggest difference between GC and ARC is that GC is run time process while ARC is operates in compile time. So when working with ARC the developer need to take care of memory in some scenarios.
How ever according to this, there is no place left for developer interaction in SWFT memory management architecture.
So how they do this? Do they have a run time process for cleaning up the memory, or there some thing else?
Swift uses ARC in a similar way as Objective-C does. ARC has been discussed extensively.
In short:
There is no garbage collector.
Objects live as long as (strong) references exist.
Strong references can't be cyclic, otherwise you leak memory. Use weak references to break cycles.
I know that the biggest difference between GC and ARC is that GC
Note that ARC is a form of GC.
is run time process while ARC is operates in compile time.
Both tracing GC and ARC do things at both compile time and at run time. ARC injects code that increments and decrements reference counts and, when the count falls to zero, collects the object and decrements all of the references it was pointing to recursively (potentially causing an unbounded amount of work to be done at run time as an arbitrarily large object graph is collected).
So when working with ARC the developer need to take care of memory in some scenarios.
Yes. You must always be careful to avoid cycles because they will never be collected.
How ARC Works
Every time you create a new instance of a class, ARC allocates a chunk
of memory to store information about that instance. This memory holds
information about the type of the instance, together with the values
of any stored properties associated with that instance.
Additionally, when an instance is no longer needed, ARC frees up the
memory used by that instance so that the memory can be used for other
purposes instead. This ensures that class instances do not take up
space in memory when they are no longer needed.
However, if ARC were to deallocate an instance that was still in use,
it would no longer be possible to access that instance’s properties,
or call that instance’s methods. Indeed, if you tried to access the
instance, your app would most likely crash.
To make sure that instances don’t disappear while they are still
needed, ARC tracks how many properties, constants, and variables are
currently referring to each class instance. ARC will not deallocate an
instance as long as at least one active reference to that instance
still exists.
To make this possible, whenever you assign a class instance to a
property, constant, or variable, that property, constant, or variable
makes a strong reference to the instance. The reference is called a
“strong“ reference because it keeps a firm hold on that instance, and
does not allow it to be deallocated for as long as that strong
reference remains.
https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/AutomaticReferenceCounting.html
In the Mac and iOS platforms, memory leaks are often caused by unreleased pointers. Traditionally, it has always been of utmost importance to check your allocs, copies and retains to make sure each has a corresponding release message.
The toolchain that comes with Xcode 4.2 introduces automatic reference counting (ARC) with the latest version of the LLVM compiler, that totally does away with this problem by getting the compiler to memory-manage your stuff for you. That's pretty cool, and it does cut lots of unnecessary, mundane development time and prevent a lot of careless memory leaks that are easy to fix with proper retain/release balance. Even autorelease pools need to be managed differently when you enable ARC for your Mac and iOS apps (as you shouldn't allocate your own NSAutoreleasePools anymore).
But what other memory leaks does it not prevent that I still have to watch out for?
As a bonus, what are the differences between ARC on Mac OS X and iOS, and garbage collection on Mac OS X?
The primary memory-related problem you'll still need to be aware of is retain cycles. This occurs when one object has a strong pointer to another, but the target object has a strong pointer back to the original. Even when all other references to these objects are removed, they still will hold on to one another and will not be released. This can also happen indirectly, by a chain of objects that might have the last one in the chain referring back to an earlier object.
It is for this reason that the __unsafe_unretained and __weak ownership qualifiers exist. The former will not retain any object it points to, but leaves open the possibility of that object going away and it pointing to bad memory, whereas the latter doesn't retain the object and automatically sets itself to nil when its target is deallocated. Of the two, __weak is generally preferred on platforms that support it.
You would use these qualifiers for things like delegates, where you don't want the object to retain its delegate and potentially lead to a cycle.
Another couple of significant memory-related concerns are the handling of Core Foundation objects and memory allocated using malloc() for types like char*. ARC does not manage these types, only Objective-C objects, so you'll still need to deal with them yourself. Core Foundation types can be particularly tricky, because sometimes they need to be bridged across to matching Objective-C objects, and vice versa. This means that control needs to be transferred back and forth from ARC when bridging between CF types and Objective-C. Some keywords related to this bridging have been added, and Mike Ash has a great description of various bridging cases in his lengthy ARC writeup.
In addition to this, there are several other less frequent, but still potentially problematic cases, which the published specification goes into in detail.
Much of the new behavior, based on keeping objects around as long as there is a strong pointer to them, is very similar to garbage collection on the Mac. However, the technical underpinnings are very different. Rather than having a garbage collector process that runs at regular intervals to clean up objects no longer being pointed to, this style of memory management relies on the rigid retain / release rules we all need to obey in Objective-C.
ARC simply takes the repetitive memory management tasks we've had to do for years and offloads them to the compiler so we never have to worry about them again. This way, you don't have the halting problems or sawtooth memory profiles experienced on garbage collected platforms. I've experienced both of these in my garbage collected Mac applications, and am eager to see how they behave under ARC.
For more on garbage collection vs. ARC, see this very interesting response by Chris Lattner on the Objective-C mailing list, where he lists many advantages of ARC over Objective-C 2.0 garbage collection. I've run into several of the GC issues he describes.
ARC won't help you with non-ObjC memory, for example if you malloc() something, you still need to free() it.
ARC can be fooled by performSelector: if the compiler can't figure out what the selector is (the compiler will generate a warning on that).
ARC will also generate code following ObjC naming conventions, so if you mix ARC and MRC code you can get surprising results if the MRC code doesn't do what the compiler thinks the names promise.
I experienced memory leaks in my application due the following 4 issues:
Not invalidating NSTimers when dismissing view controllers
Forgetting to remove any observers to NSNotificationCenter when dismissing the view controller.
Keeping strong references to self in blocks.
Using strong references to delegates in view controller properties
Luckily I came across the following blog post and was able to correct them: http://www.reigndesign.com/blog/debugging-retain-cycles-in-objective-c-four-likely-culprits/
ARC will also not manage CoreFoundation types. You can 'bridge' them (Using CFBridgingRelease()) but only if you are going to use it as an Objective-C/Cocoa object. Note that CFBridgingRelease just decrements the CoreFoundation retain count by 1 and moves it to Objective-C's ARC.
Xcode 9 provides a great tool for finding that kind of issues. It is called: "Debug Memory Graph".
Using it you can find your leaked object by class type and you can see clearly who holds a strong reference to it, by releasing it from there solves your problem. It is also detects memory cycles.
See more info about how to use it