Object Oriented Programming - Memory Management

From SwinBrain

In Object Oriented Programming, Objects typically reside on the Heap. In languages like C# and Java you cannot create objects that reside on stack, so in these languages all objects reside on the heap resulting in a distinction between Value and Reference Types. Languages like C++, Objective C [1], and Object Pascal all provide a means of allocating objects either on the stack or on the heap. When your objects are allocated on the heap you need a means of freeing the memory allocated to them when they are no longer needed. There are a number of different approaches that object oriented programming languages take to this problem.

Memory management is a simple concept, but is complicated by the interconnected nature of object oriented programs. It may be difficult to determine when an object is safe to delete.

Freeing and Allocating Memory Manually

Languages like C++ and Object Pascal require that you manage memory yourself. These languages two functions for memory management. One to allocate space on the heap, and another to free the space used.

Advantages: You are in complete control in this environment, and can provide fine control over when objects are created and freed. This level of control is particularly helpful when working with devices that have relatively small amount of RAM available for applications (for instance, a mobile phone or an embedded engine controller within a car)

Disadvantages: Freeing objects adds complexity that programmers have to carefully manage. Failing to free an object will result in a memory leak, while prematurely freeing an object has the potential to cause significant runtime problems that may be hard to debug. When working in teams these problems become even more of an issue as the memory management of your objects needs to be clearly understood by all developers working on the program. The composite aggregation relationship in a UML class diagram can be used to indicate that when the whole is freed it frees its parts.

  • C++ uses obj = new class_name(params) to create an object, and delete obj to free the space allocated to these objects. new (C++) on wikipedia
  • Object Pascal uses obj := class_name.Create(params) to create an object, and obj.Free() to free the space allocated to the object.

Reference Counting

Reference counting is one approach to overcoming the issues of manual memory management. With reference counting each object maintains a count of the number of references that refer to it. When new things refer to the object its reference count is increased, when a reference is removed the count is reduced. The object is then responsible for releasing itself when its reference count reaches 0.

Advantages: Objects are freed when their reference count reaches 0, meaning they are freed as soon as they are no longer needed.

Disadvantages: Circular references mean that objects are never released. For example if A -> B -> C -> A then the reference count of each is 1, and yet no other objects have references to any in this loop. This issue can be avoided through specific loop detection code or by appropriate diligence from developers.

  • Reference counting is used internally by Python to manage the object lifetime. No interaction is required by the programmer. Python includes cycle detecting code that releases any object that is accessible only via a cycle.
  • Objective C uses manual reference counting.
    • Basic rules are:
      1. You own any objects you create with methods that start with alloc or new: e.g. obj = [SGPoint2D alloc];, obj = [Blah newObject].
      2. You own any objects you create with a method that contains the word copy: obj = [Foo mutableCopy];.
      3. If you own an object you must release it when you have finished with it using [obj release]; or [obj autorelease];.
      4. If you do not own an object you must not release it.
      5. You can take ownership of an object using retain: e.g. [obj retain];.
    • Details:
      • Object allocation (alloc) sets the reference count to 1.
      • Calling retain on an object increases its reference count.
      • Calling release on an object decreases its reference count, if the count is 0 then the object is freed.
      • Methods starting with alloc or new or containing the word copy do not autorelease the objects they return, and therefore ownership is transferred to the caller.
      • Other methods that return objects (either as out parameters, or the return value) will have assumed responsibility for the lifetime of these objects. If you want to keep using the object you should retain it. Helper methods that create objects such as [SGPoint2D point2DForData: dat] return newly created objects that have been added to the auto release pool. These objects are freed when the pool is drained, unless they are retained by the caller.
      • Release can be delayed by adding the object to the AutoReleasePool using [obj autorelease]. These objects are freed when the AutoReleasePool is drained[2]. This allows objects to be returned in a state that means they will be freed unless they are retained by the receiving code.
      • For full details see Memory Management Programming Guide for Cocoa.
      • Developers need to be careful to assign ownership carefully to ensure cycles do not occur. As you are in control of the reference count these issues can be avoided.

Garbage Collection

The latest evolution of memory management looks to address the issues of circular reference counts by delegating memory management to the program runtime. With this kind of memory management there is a Garbage Collector that is responsible for freeing objects when they are no longer accessed. This is done by identifying those objects that cannot be reached from root links such as stack and global variables. Once these objects are identified the garbage collector frees the memory they are using. This typically involves calling a destructor or finaliser method to indicate that the object is about to be freed[3].

Advantages: The developers are released from having to deal with memory issues. This significantly simplifies the process of developing software, regardless of the number of developers working in the team.

Disadvantages: Requires overhead in the runtime to check object links and objects are not freed until the garbage collector runs, resulting in a larger memory footprint than is actually required.

Object Oriented Programming » Memory Management

  1. Objects in Objective C should always be referenced by a pointer allocated on the heap, but the language does allow stack based allocations of these values.
  2. SwinGame drains the current pool each time you call processEvents
  3. Its important to note that the destructor or finaliser method is not actually freeing the object, its a notification that the object is no longer referenced.