Garbage Collection

Alex Harui
Flex SDK
Adobe Systems, Inc.

2005 Adobe Systems Incorporated. All Rights Reserved.

1

Garbage Collection: Atomic Model

By “Atomic Model” I mean that this is a model of how garbage collection works in the player, not a technical, exact description. That’s because:

The actual behavior is complex and difficult to describe (just like we don’t really know what atoms are made of, we just have a model which works for us). The player may change it at some point This model has worked for me so far.

 

2005 Adobe Systems Incorporated. All Rights Reserved.

2

Flash Player Memory Management

Many Flash memory allocations are small and of common sizes

Lots of small, frequent OS memory allocations can be slow

 

Flash grabs large chunks of memory from the OS less often A single large chunk is carved into a pool of small blocks of a fixed size Big chunks 256 bytes for Bitmaps, Files, etc are not pooled
256 256 256 256 256 256 256 256 bytes bytes bytes bytes bytes bytes bytes bytes 512 bytes 512 bytes 512 bytes 512 bytes … 512 bytes

… 256 bytes

2005 Adobe Systems Incorporated. All Rights Reserved.

3

Flash Player Memory Management

After a pool is used up, another large chunk is allocated from the OS

512 bytes 512 bytes Used Unused 512 bytes 512 bytes … 512 bytes

512 bytes 512 bytes 512 bytes 512 bytes … 512 bytes

2005 Adobe Systems Incorporated. All Rights Reserved.

4

Garbage Collection Does Not Run Constantly
 

“The garbage man only comes Friday morning” When something is freed, its block will not always be re-used by the next allocation. Assume that we have use 100000 bytes so far.

512 bytes 512 bytes Used Unused 512 bytes 512 bytes … 512 bytes System.totalMemory = 100000 bytes

2005 Adobe Systems Incorporated. All Rights Reserved.

5

Garbage Collection Does Not Run Constantly
 

Assume that a Foo instance is 512 bytes. When allocated, another 512 bytes is used from the pool
foo = new Foo()

512 bytes 512 bytes Used Unused 512 bytes 512 bytes … 512 bytes System.totalMemory = 100512 bytes

2005 Adobe Systems Incorporated. All Rights Reserved.

6

Garbage Collection Does Not Run Constantly

When “freed”, it is not marked unused, only GC will mark it unused. Memory stays at 100512 bytes. “Putting it in thefoo = new Foo(); trash can doesn’t cause the can to be emptied” foo = null;
512 bytes 512 bytes Used Unused Unused But not GC’d 512 bytes 512 bytes … 512 bytes System.totalMemory = 100512 bytes

 

2005 Adobe Systems Incorporated. All Rights Reserved.

7

Garbage Collection Does Not Run Constantly

When another Foo is allocated, it might take a new block from the pool Memory now is 101024 bytes.
foo = new Foo(); foo = null; foo = new Foo(); 512 bytes 512 bytes Used Unused Unused But not GC’d 512 bytes 512 bytes … 512 bytes System.totalMemory = 101024 bytes

2005 Adobe Systems Incorporated. All Rights Reserved.

8

Garbage Collection Is Only Triggered By Allocations

When a pool starts to fill up, there will be an attempt to collect before allocating from the OS. “When renting videos, they don’t go through the recently returned videos unless all the ones on the shelf are gone”

512 bytes 512 bytes Used Unused Unused But not GC’d 512 bytes 512 bytes … 512 bytes

Almost out!, Run GC!

2005 Adobe Systems Incorporated. All Rights Reserved.

9

Garbage Collection Is Only Triggered By Allocations

Since GC is only triggered by allocations, it means that you can watch an idle application forever and its memory usage will not change

2005 Adobe Systems Incorporated. All Rights Reserved.

10

Garbage Collection Does Not Run Completely

The collector is not guaranteed to find all collectible blocks in one pass

Don’t want to interfere with rendering and interaction

Thus memory may never return to the initial point
Before 512 bytes 512 bytes Used Unused Unused But not GC’d 512 bytes 512 bytes … 512 bytes 512 bytes 512 bytes 512 bytes 512 bytes … 512 bytes

2005 Adobe Systems Incorporated. All Rights Reserved.

11

Garbage Collection Does Not Run Completely

The collector is not guaranteed to find all collectible blocks in one pass

Don’t want to interfere with rendering and interaction

Thus memory may never return to the initial point
After 512 bytes 512 bytes Used Unused Unused But not GC’d 512 bytes 512 bytes … 512 bytes 512 bytes 512 bytes 512 bytes 512 bytes … 512 bytes

2005 Adobe Systems Incorporated. All Rights Reserved.

12

Garbage Collection Does Not Always Free OS Memory

The collector will attempt to move blocks from one large chunk to another to free an entire chunk to the OS

Won’t always be able to accomplish that in one pass

Thus memory may never return to the initial point
Before 512 bytes 512 bytes Used Unused Unused But not GC’d 512 bytes 512 bytes … 512 bytes 512 bytes 512 bytes 512 bytes 512 bytes … 512 bytes

2005 Adobe Systems Incorporated. All Rights Reserved.

13

Garbage Collection Does Not Always Free OS Memory

The collector will attempt to move blocks from one large chunk to another to free an entire chunk to the OS

Won’t always be able to accomplish that in one pass

Thus memory may never return to the initial point
After 512 bytes 512 bytes Used Unused Unused But not GC’d 512 bytes 512 bytes … 512 bytes 512 bytes 512 bytes 512 bytes 512 bytes … 512 bytes Eligible for Release to OS

2005 Adobe Systems Incorporated. All Rights Reserved.

14

Garbage Collection Is Not Predictable

Since GC is not predictable, it means that cannot scientifically prove your application is not leaking memory But you can get a sense empirically

2005 Adobe Systems Incorporated. All Rights Reserved.

15

Detecting Memory Leaks

Even small changes like the timing or location of mouse and keyboard events can affect totalMemory

Therefore, human interaction is not a good test.

You are generally only concerned about repeatable sequences
 

Popup dialogs coming and going Modules loading and unloading

If you repeat these sequences often over a long period of time, the amount of totalMemory will hit some maximum value and stay at or below it if you are not leaking memory.

2005 Adobe Systems Incorporated. All Rights Reserved.

16

Detecting Memory Leaks

The next release of Flex should have memory leak diagnostics. Until then:

Automate the sequence in ActionScript so it runs w/o human intervention. One technique is to use switch statements and faked mouse or keyboard events.

2005 Adobe Systems Incorporated. All Rights Reserved.

17

Detecting Memory Leaks
private function doit():void { // call this on some interval var m:MouseEvent; switch (currentStep) { case 0: m = new MouseEvent(MouseEvent.CLICK); b.dispatchEvent(m); // click app button to open dialog break; case 1: case 2: // wait for dialog to appear break; case 3: m = new MouseEvent(MouseEvent.CLICK); var o:Object = loginDialog; o.b.dispatchEvent(m); case 4: case 5: break; default: currentStep = -1; break; } currentStep++; } // start over again // click dialog button to close dialog

2005 Adobe Systems Incorporated. All Rights Reserved.

18

Where To Find Memory Leaks

For a repeatable sequence, properties referencing objects cannot be the cause of a leak.

They will get reassigned every time through the sequence so they will drop their reference to the previous object

Arrays, Objects used as Maps, Dictionary are common causes

Run the sequence once, see how many things are in the arrays and object maps Run it several more times, are there more things?

Failure to remove event listeners

2005 Adobe Systems Incorporated. All Rights Reserved.

19

How Garbage Collection Works
   

Start at known tops of Object trees. Mark them and any objects they reference Go through the heap and free anything that isn’t marked. Three tops of Object trees:
  

Stage ApplicationDomain/Class definitions Stack/Local Variables

2005 Adobe Systems Incorporated. All Rights Reserved.

20

How Garbage Collection Works

Stage

Starting from Stage you can follow arrows to all blue boxes

<mx:Application … > <mx:Model id=“Model” /> <mx:VBox> <mx:Button />

Used Unused Unused But not GC’d

.application

Application

Model Removed Popup VBox .root

SystemManager Stage

Button Popup’s Button

2005 Adobe Systems Incorporated. All Rights Reserved.

21

How Garbage Collection Works

ApplicationDomain\Class Definitions

Only static variables matter here.

public class Application { public static var application:Object; public var layoutType:String;

Used Unused Unused But not GC’d

.application

Application

Model Removed Popup VBox

mx.core.Application ApplicationDomain

Button Popup’s Button

2005 Adobe Systems Incorporated. All Rights Reserved.

22

How Garbage Collection Works

Stack/Local Variables
PopUpManager.createPopUp(Dialog, this); class PopUpManager { public static function createPopUp(popUpClass:Class,…) { var popUp = new popUpClass();

Dialog instance Used Unused Unused But not GC’d class Dialog ApplicationDomain Application instance popUp return address this Dialog Stack

2005 Adobe Systems Incorporated. All Rights Reserved.

23

Removing EventListeners

Listeners on child objects generally do not cause memory leaks. Removing the following addEventListener isn’t required (but good practice)
override protected function createChildren():void { child = new ChildComponent(); addChild(child); child.addEventListener(“click”, clickHandler); Application clickHandler .child ChildComponent clickListeners

Used Unused Unused But not GC’d

.application

Stage

.root
24

SystemManager

2005 Adobe Systems Incorporated. All Rights Reserved.

Removing EventListeners

The child’s list of listeners gets a reference to the parent’s method After removing the child, there is no path from Stage to the child.

Used Unused Unused But not GC’d

.application

Application clickHandler

ChildComponent clickListeners

Stage

.root
25

SystemManager

2005 Adobe Systems Incorporated. All Rights Reserved.

Removing EventListeners
 

Listening to parent objects does cause memory leaks. Removing the following addEventListener is required

There are two paths to the PopUp

override protected function mouseDownHandler(…):void { systemManager.addEventListener(“mouseUp”, mouseUpHandler);

.popupChildren

PopUp mouseUpHandler mouseUpListeners

Used Unused Unused But not GC’d

Stage

2005 Adobe Systems Incorporated. All Rights Reserved.

.root
26

SystemManager

Removing EventListeners

Use of weak reference listeners may be easier here.

Otherwise you have to check to see if you OR your parents have been removed from the display list.

Removing the following addEventListener is not required
override protected function mouseDownHandler(…):void { systemManager.addEventListener(“mouseUp”, mouseUpHandler, false, 0, true);

.popupChildren

PopUp mouseUpHandler weak ref mouseUpListeners

Used Unused Unused But not GC’d

Stage

2005 Adobe Systems Incorporated. All Rights Reserved.

.root
27

SystemManager

Summary
   

Garbage Collection is triggered by allocation not deletion Garbage Collection is not predictable Next Release should have memory diagnostic tools Until then, automate repeatable sequences

totalMemory should reach a maximum value over time

Event Listeners cause references in the opposite direction than you may think.

The dispatcher references the listener.

2005 Adobe Systems Incorporated. All Rights Reserved.

28

Sign up to vote on this title
UsefulNot useful