This document summarizes key aspects of memory management in RubyMotion. It discusses how Ruby uses garbage collection while iOS uses reference counting. Developers need to avoid retain cycles when objects strongly reference each other. Using WeakRef allows child objects to weakly reference parent objects to prevent retain cycles from occurring. The document demonstrates examples of retain cycles and how to avoid them using WeakRef. It also provides information on how to use Xcode Instruments to detect memory leaks and profile memory usage in RubyMotion applications.
2. About Me
• Software developer @TerribleLabs
• Lover of TDD and little ‘a’ agile
• Experienced Rails developer, budding RubyMotion
developer
• mdenomy on twitter, gmail, github
• Blog at http://mdenomy.wordpress.com
3. Memory Management in
Ruby (MRI)
• You probably haven’t had to think about memory
management a lot in Ruby (or other languages).
• Ruby automatically allocates memory for you and
frees it up using garbage collection mechanism.
• Ruby uses a “mark and sweep” algorithm to find
objects that are actively being used and ones that
are available to be freed up.
4. Mark and Sweep
(the simplified version)
• GC walks your code to find
“active” objects
• Objects no longer used are
swept away
• MRI 2.1, JRuby, and Rubinius use more sophisticated
“generational” mechanisms
• Check out Pat Shaughnessy’s “Ruby Under
a Microscope” for more GC goodness
5. Memory Management in iOS
• Objective C uses “reference counting” to determine
when objects can be freed up.
• The number of references to each object is tracked
• set to 1 when the object is created
• incremented when another object references it
• decremented when an object releases it
• available to be freed up when count reaches zero
6. The Dark Ages
• Developers manually managed reference count in
Objective-C using “Manual Retain-Release MRR”
• “retain” incremented reference count
• “release” decremented reference count
• Under the covers, retain/release still used, but no
longer need to manually do it since Automatic
Reference Counting (ARC)
7. Automatic Reference Counting
(ARC)
• In ARC, calls to retain and release are inserted into the
code automatically at compile time
• References can be strong or weak
• strong - counted as an owner in the “retain-release”
cycle
• weak - not an owner in “retain-release” cycle. Gets
set to nil if object pointed to is released.
• Weak references allow us to avoid “retain cycles”
9. What Does This Have To Do
With RubyMotion
• Still bound by memory management constructs of
Objective-C
• Need to avoid retain cycles
• WeakRef class allows us to create Objective-C
weak references to avoid retain cycles
11. How Do We Detect
Memory Leaks
• Xcode Instruments can be used to examine
allocations, memory usage, leaks, etc.
• Launch from command line
rake profile # Same as profile:simulator
rake profile:device # Run a build on the device through Instruments
rake profile:device:templates # List all built-in device Instruments templates
rake profile:simulator # Run a build on the simulator through Instruments
rake profile:simulator:templates # List all built-in Simulator Instruments templates
• Can also attach to running instance
12. Can We Please
See Some Code
• Very simple example of creating a retain cycle
• No extra gems to keep memory “noise” to a
minimum
• https://github.com/mdenomy/motion-weakref-demo
• See README and labels for different conditions
• Use Xcode Instruments to examine memory usage
13. Memory Usage ‘notifier’ tag
• No retain cycle because Notifier does not have reference
to ToDoItem
• Memory increases on create item, but returns to baseline
on delete item
14. Memory Usage ‘retain-cycle’ tag
• Notifier has a strong reference to parent ToDoItem,
creating retain cycle
• Memory increases each call to create item, but is not freed
on delete item. Memory leak!!!
15. Memory Usage ‘weak-ref’ tag
• Notifier has a weak reference to parent ToDoItem, so no
retain cycle.
• Memory usage follows expected pattern of increasing on
create item and returning to baseline on delete item
16. Summary
• Reference counting creates the possibility to create
memory leaks via retain cycles.
• Avoid retain cycles by using WeakRef in
RubyMotion when child needs reference to parent
• Xcode Instruments can help identify memory leaks
or other allocation errors