Talking Trash Michael Labriola Senior Consultant Digital Primates @mlabriola Page 0 of 59
Who am I? <ul><li>Michael Labriola </li></ul><ul><li>Senior Consultant </li></ul><ul><li>Digital Primates </li></ul><ul><l...
What are we going to cover? <ul><li>Memory in Flash Player </li></ul><ul><li>Garbage Collection as it exists today </li></...
Disclaimer <ul><li>I am going to tell you lies. </li></ul><ul><li>Even at this depth, we will need to gloss over some deta...
Memories <ul><li>You have some choices in (programming) life.  </li></ul><ul><li>You can take full responsibility for aski...
What is GC <ul><li>GC (Garbage Collection) is a way to automatically manage memory. </li></ul><ul><li>As an oversimplifica...
Why Proxy? <ul><li>By proxying our access to the memory our program needs, GC can keep track of what objects are using mem...
Dangling References <ul><li>If you manually allocate and free memory you can cause dangling references. What happens if th...
Double Free <ul><li>What happens if you accidently try to free the same memory twice? What if it has already been reused? ...
Real Leaks <ul><li>What happens if you don’t free the memory before you lose access to it? </li></ul>Page 3 of 59 Memory2 ...
GC Instead <ul><li>GC takes care of these situations by determining when a chunk of memory is no longer accessible and fre...
GC How <ul><li>The rest of this presentation is about that complication. </li></ul><ul><li>It is about how GC decides when...
Allocation <ul><li>Flash Player uses a page allocator (GCHeap) to allocate large chunks from system memory (megabytes). In...
Pages <ul><li>Those 4k pages are then used by GC to provide memory for many objects in the system. </li></ul>Page 3 of 59 ...
Much <ul><li>The memory we are discussing right now is called heap   memory. It is responsible for *much* but not all of t...
Stack <ul><li>A stack is a data structure (think pile of papers on your desk) which is managed by two operations: pushing ...
<ul><li>Now imagine removing (popping) item 3 and adding a new (pushing) item 4. In Flash Player we have a memory structur...
Local Variable Declaration <ul><li>As you declare local method variables in ActionScript, they are pushed onto the stack. ...
Method Calls <ul><li>As you call methods, each of their local variables are pushed onto a stack as well. </li></ul>functio...
Method Calls <ul><li>There is also other information contained on the stack about where to return when this method is comp...
Method Calls <ul><li>Stack memory is frequently reused as items are pushed onto and popped off the stack. </li></ul>functi...
Instances <ul><li>References to complex objects may also exist on the stack, but memory allocated for those objects comes ...
Instances <ul><li>Arguments passed to methods are also pushed into stack memory. </li></ul>Stack Memory Heap Memory functi...
Instances <ul><li>When a method returns, the stack is unwound so that the memory can be reused. </li></ul>function doThing...
Freeing <ul><li>Now that we have memory and it’s all in use, we need to find a way to deallocate (free) it. </li></ul><ul>...
Roots <ul><li>In traditional programming models, you manage your own memory. Let’s call this unmanaged memory. </li></ul><...
Hybrid <ul><li>The current Flash Player is a  conservative mark and sweep garbage collector with deferred reference counti...
Reference Counting <ul><li>Reference counting is a very easy-to-understand way of keeping track of objects that can be rem...
Reference Counting <ul><li>Looking at the following code, how many references does the object assigned to  a  have? How ma...
Reference Counting <ul><li>What if we set  a  to null? Can anything be collected? </li></ul>Page 3 of 59 ObjectA a = new O...
Reference Counting <ul><li>What if instead we set  b  to null? Can anything be collected? </li></ul>Page 3 of 59 ObjectA a...
Reference Counting <ul><li>What if instead we set  a  and  b  to null? Notice how this will eventually cascade? </li></ul>...
Circular Reference <ul><li>What if  a  also references  b ? Can these ever be collected via this technique? </li></ul>Page...
Reference Counting Issues <ul><li>Obviously the circular reference issue is a problem for reference counting, but there ar...
Frequent Allocations <ul><li>To address the issue we simply don’t reference count items on the stack.  </li></ul><ul><li>T...
Missing Stack Count <ul><li>If  x  doesn’t count as a reference to ObjectA, then how many references does ObjectA have? Wh...
Zero Count Table <ul><li>Instead of immediately destroying ObjectA when its reference count reaches 0, it is added to a Ze...
Zero Count Table <ul><li>When the ZCT is full, it can be reaped to destroy objects. If an object made it to the ZCT, then ...
Back to Circles <ul><li>The combination of those techniques are called Deferred Reference Counting. </li></ul><ul><li>Whic...
Mark and Sweep <ul><li>The other technique used by the Flash Player garbage collector is called mark and sweep. </li></ul>...
Marking <ul><li>You start with a tree of Objects. In this case Object A is a GC root. </li></ul>Page 3 of 59 Object A Obje...
Marking <ul><li>From Object A all paths are followed, marking each child that is encountered. </li></ul>Page 3 of 59 Objec...
Remainder <ul><li>Anything that is not marked is not reachable. That means it can be discarded. </li></ul>Page 3 of 59 Obj...
Tangent – Weak References <ul><li>Many of you may have heard of weak references and have heard advice such as:  </li></ul>...
Tangent – Weak References <ul><li>Additionally, the Dictionary class can be constructed to use weak keys. </li></ul><ul><l...
Weak Reference <ul><li>I like to think of it as adding a path that cannot be travelled by the marking. If the object has n...
Tangent – Weak References <ul><li>So, should you always use weak references? </li></ul><ul><li>Absolutely not.  </li></ul>...
Back on Track <ul><li>For some strange reason, people don’t like their application to pause noticeably while garbage colle...
Work Queue <ul><li>So, we make a work queue. We push all of the roots onto the work queue and we process. When the queue i...
Hello Complexity <ul><li>The problem with not doing all the marking at once introduces serious complexity. Imagine if your...
Tri-Color <ul><li>To handle the complexity of managing this type of garbage collection marking incrementally, Flash Player...
Work Queue Start <ul><li>We start by putting all the roots on the queue. This makes them gray. </li></ul>Page 3 of 59 Work...
Queue Progress <ul><li>As the queue is processed, gray becomes black, white becomes gray. </li></ul>Page 3 of 59 Work Queu...
New Addition <ul><li>In most cases, new objects can be added at will, but we have a problem when a white object is added t...
Added to the Queue <ul><li>So, whenever a white object is added to black, it immediately gets added to the work queue. If ...
Being Conservative <ul><li>So far that explains most of the phrase  conservative mark and sweep garbage collector with def...
Pointer or Integer <ul><li>When the garbage collector comes across certain values it is difficult to tell if the value is ...
Minor Leaks <ul><li>This can mean that, on occasion, an object may not be collected because there is an integer somewhere ...
Moving On <ul><li>So, now you have a good sense of what GC is doing to decide when your memory is collected. </li></ul><ul...
Controlling GC <ul><li>Leaving aside hacky approaches for the moment, you have some minimal ability to influence and contr...
Imminence <ul><li>As you know, it takes a while for to mark all of the objects in the system. This is done incrementally. ...
Something Incubating <ul><li>The Flash Player Incubator introduces a new function: </li></ul><ul><li>class System { </li><...
Pause Now <ul><li>When you call pauseForGCIfCollectionImminent() the value you pass is compared against the collectors cur...
Wait, pause now? <ul><li>Why in the world would you want to pause? </li></ul><ul><li>The player is going to pause at some ...
Advice Examples <ul><li>A  bad  time to collect: </li></ul><ul><li>function doIt() { </li></ul><ul><li>startComplexAnimati...
Giving Back <ul><li>Way back in the beginning of this journey, we talked about how the GCHeap allocates megabytes and give...
<ul><li>Objects are allocated on those pages and some are collected. Over time we get fragmentation. </li></ul>Fragmentati...
<ul><li>That fragmentation makes it almost impossible to judge if you have memory leaks by looking at system memory alone....
<ul><li>Now, I would like to wildly speculate. </li></ul><ul><li>Well, okay, perhaps not wildly. If one were to pay attent...
<ul><li>Going back to fragmentation: why don’t we just collapse all of these objects into a single page and free the other...
<ul><li>Well, it goes back to the point that Flash doesn’t really know where references to objects are. Back when we discu...
<ul><li>There is a solution to this problem, though. We could keep better track of what is actually a pointer and what isn...
<ul><li>And, for fun, here is a bunch of information about implementing exact tracing in Tamarin: </li></ul><ul><li>Exact ...
<ul><li>So, speculating just a bit more, why else might we want to be able to move objects? </li></ul><ul><li>Well, it tur...
<ul><li>Ephemeral, also known as generational, garbage collection is all based on a simple hypothesis: </li></ul><ul><li>T...
<ul><li>In a generational garbage collection scheme, you keep objects in separate areas depending on how long they have be...
<ul><li>When the youngest region is full, we promote objects still referenced in older memory and reuse the youngest area....
<ul><li>If using generation garbage collection becomes a reality, then the need for reference counted objects and the over...
Contact Information Michael Labriola http://twitter.com/mlabriola Page 59 of 59
Upcoming SlideShare
Loading in …5
×

Talking trash

6,964 views

Published on

Presentation given at Flash the City conference in New York, 2011

Published in: Technology
0 Comments
3 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
6,964
On SlideShare
0
From Embeds
0
Number of Embeds
4,535
Actions
Shares
0
Downloads
42
Comments
0
Likes
3
Embeds 0
No embeds

No notes for slide

Talking trash

  1. 1. Talking Trash Michael Labriola Senior Consultant Digital Primates @mlabriola Page 0 of 59
  2. 2. Who am I? <ul><li>Michael Labriola </li></ul><ul><li>Senior Consultant </li></ul><ul><li>Digital Primates </li></ul><ul><li>Client side architect specializing in Adobe Flex </li></ul><ul><ul><li>Lead architect and developer of FlexUnit 4 </li></ul></ul><ul><ul><li>Benevolent Dictator of the Open Spoon Project </li></ul></ul><ul><li>Team Mentor </li></ul><ul><li>Architect of applications deployed worldwide </li></ul><ul><li>Fan of disassembling things </li></ul>Page 2 of 59
  3. 3. What are we going to cover? <ul><li>Memory in Flash Player </li></ul><ul><li>Garbage Collection as it exists today </li></ul><ul><li>A tiny bit of coming soon </li></ul><ul><li>Some wild speculation on what’s next </li></ul>Page 3 of 59
  4. 4. Disclaimer <ul><li>I am going to tell you lies. </li></ul><ul><li>Even at this depth, we will need to gloss over some details and treat them in a simplified manner to make it through. </li></ul><ul><li>Further, most of this has been learned by reading code from the Tamarin project. It is likely the same as in Flash Player, but I can’t know for sure. </li></ul>Page 3 of 59
  5. 5. Memories <ul><li>You have some choices in (programming) life. </li></ul><ul><li>You can take full responsibility for asking for memory and returning it when you are done. </li></ul><ul><li>You can employ another entity to do that work for you. </li></ul><ul><li>You can do a combination of those two, but seriously, let’s keep this simple. </li></ul>Page 3 of 59
  6. 6. What is GC <ul><li>GC (Garbage Collection) is a way to automatically manage memory. </li></ul><ul><li>As an oversimplification let’s think about it this way — </li></ul><ul><li>GC proxies our access to memory: </li></ul>Page 3 of 59 Memory GC Program Code
  7. 7. Why Proxy? <ul><li>By proxying our access to the memory our program needs, GC can keep track of what objects are using memory. This removes the responsibility of remembering when and where to free (deallocate) memory. </li></ul><ul><li>To understand what GC is trying to do for you, let’s look at what can go wrong if you try to do it manually. </li></ul>Page 3 of 59
  8. 8. Dangling References <ul><li>If you manually allocate and free memory you can cause dangling references. What happens if the memory below does not exist when it is accessed? </li></ul>Page 3 of 59 Memory p1 p2 memory = allocate( size ); p1 = memory; p2 = memory; free( memory ); trace( p1.toString() ); trace( p2.toString() );
  9. 9. Double Free <ul><li>What happens if you accidently try to free the same memory twice? What if it has already been reused? </li></ul>Page 3 of 59 Memory2 memory1 = allocate( size ); free( memory1 ); memory2 = allocate( size ); free( memory1 );
  10. 10. Real Leaks <ul><li>What happens if you don’t free the memory before you lose access to it? </li></ul>Page 3 of 59 Memory2 p1 p1 = allocate( size ); p2 = allocate( size ); p1 = p2; Memory1
  11. 11. GC Instead <ul><li>GC takes care of these situations by determining when a chunk of memory is no longer accessible and freeing it. </li></ul><ul><li>This is helpful, but GC will never understand your program logic, meaning that it will need to do more work to determine things you already know (i.e., you no longer need a chunk of memory). </li></ul><ul><li>So, GC has advantages but will also necessarily be slower and more complicated. </li></ul>Page 3 of 59
  12. 12. GC How <ul><li>The rest of this presentation is about that complication. </li></ul><ul><li>It is about how GC decides when and where to allocate and free memory and all of the overhead and processes that go into that decision. </li></ul>Page 3 of 59
  13. 13. Allocation <ul><li>Flash Player uses a page allocator (GCHeap) to allocate large chunks from system memory (megabytes). In turn GCHeap gives 4k chunks (pages) to the GC memory manager as needed. </li></ul>Page 3 of 59 System Memory 4k 4k 4k GCHeap GC
  14. 14. Pages <ul><li>Those 4k pages are then used by GC to provide memory for many objects in the system. </li></ul>Page 3 of 59 4k GC Object A Object B Object C
  15. 15. Much <ul><li>The memory we are discussing right now is called heap memory. It is responsible for *much* but not all of the storage in the system </li></ul><ul><li>For our purposes, there are two types of memory we care about: heap and stack. </li></ul>Page 3 of 59
  16. 16. Stack <ul><li>A stack is a data structure (think pile of papers on your desk) which is managed by two operations: pushing and popping. Pushing means adding something to the top stack, popping means removing. </li></ul>In this data structure, the only way to get something in the middle is the remove the things above it. Item 1 Item 2 Item 1 Item 2 Item 3
  17. 17. <ul><li>Now imagine removing (popping) item 3 and adding a new (pushing) item 4. In Flash Player we have a memory structure like this, affectionately called ‘the stack.’ </li></ul>Altering the Stack Item 1 Item 2 Item 1 Item 2 Item 3 Item 1 Item 2 Item 4
  18. 18. Local Variable Declaration <ul><li>As you declare local method variables in ActionScript, they are pushed onto the stack. </li></ul>function doThing() { var a:int; var b:int; var c:Number; } a b c
  19. 19. Method Calls <ul><li>As you call methods, each of their local variables are pushed onto a stack as well. </li></ul>function doThing() { var a:int; var b:int; var c:Number; someMethod(); } function someMethod() { var x:int; } a b c x
  20. 20. Method Calls <ul><li>There is also other information contained on the stack about where to return when this method is complete. </li></ul>function doThing() { var a:int; var b:int; var c:Number; someMethod(); } function someMethod() { var x:int; } a b c x doThing
  21. 21. Method Calls <ul><li>Stack memory is frequently reused as items are pushed onto and popped off the stack. </li></ul>function doThing() { var a:int; var b:int; var c:Number; someMethod1(); someMethod2(); } function someMethod()1 { var x:int; } function someMethod2() { var y:int; } a b c y doThing
  22. 22. Instances <ul><li>References to complex objects may also exist on the stack, but memory allocated for those objects comes from the heap. </li></ul>Stack Memory Heap Memory function doThing() { var a:int; var o:Object; o = new Object(); } a o Object A
  23. 23. Instances <ul><li>Arguments passed to methods are also pushed into stack memory. </li></ul>Stack Memory Heap Memory function doThing() { var a:int; var o1:Object; o1 = new Object(); doIt( o1 ); } function doIt( o2 ) { var b:int; } Object A a o1 doIt o2 b
  24. 24. Instances <ul><li>When a method returns, the stack is unwound so that the memory can be reused. </li></ul>function doThing() { var a:int; var o1:Object; o1 = new Object(); doIt( o1 ); } function doIt( o2 ) { var b:int; } Stack Memory Heap Memory a o1 Object A
  25. 25. Freeing <ul><li>Now that we have memory and it’s all in use, we need to find a way to deallocate (free) it. </li></ul><ul><li>The premise behind GC is that we only free memory that is no longer needed. So how do we figure out how things are no longer needed? </li></ul><ul><li>First, some terms. </li></ul>Page 3 of 59
  26. 26. Roots <ul><li>In traditional programming models, you manage your own memory. Let’s call this unmanaged memory. </li></ul><ul><li>In a managed memory model, we ask the system to manage the lifetime (birth through death) of our memory. </li></ul><ul><li>The first chunk of managed memory asked for from unmanaged memory is called a root, or a GCRoot. </li></ul><ul><li>The garbage collector is aware of all roots. They serve as a starting point for things we are about to cover. </li></ul>Page 3 of 59
  27. 27. Hybrid <ul><li>The current Flash Player is a conservative mark and sweep garbage collector with deferred reference counting. </li></ul><ul><li>Let’s take those in reverse. </li></ul>Page 3 of 59
  28. 28. Reference Counting <ul><li>Reference counting is a very easy-to-understand way of keeping track of objects that can be removed from the system. </li></ul><ul><li>Imagine each object has an extra property called refCount that keeps track of the number of references to that object. </li></ul>Page 3 of 59
  29. 29. Reference Counting <ul><li>Looking at the following code, how many references does the object assigned to a have? How many does b have? For our purposes, assume a and b are global variables. </li></ul>Page 3 of 59 ObjectA a = new ObjectA(); b = new ObjectB(); b.prop = a ; ObjectB a b ObjectA: 2 ObjectB: 1
  30. 30. Reference Counting <ul><li>What if we set a to null? Can anything be collected? </li></ul>Page 3 of 59 ObjectA a = new ObjectA(); b = new ObjectB(); b.prop = a; a = null; ObjectB a b ObjectA: 1 ObjectB: 1
  31. 31. Reference Counting <ul><li>What if instead we set b to null? Can anything be collected? </li></ul>Page 3 of 59 ObjectA a = new ObjectA(); b = new ObjectB(); b.prop = a; b = null; ObjectB a b ObjectA: 2 ObjectB: 0
  32. 32. Reference Counting <ul><li>What if instead we set a and b to null? Notice how this will eventually cascade? </li></ul>Page 3 of 59 ObjectA a = new ObjectA(); b = new ObjectB(); b.prop = a; a = b = null; ObjectB a b ObjectA: 1 ObjectB: 0
  33. 33. Circular Reference <ul><li>What if a also references b ? Can these ever be collected via this technique? </li></ul>Page 3 of 59 ObjectA a = new ObjectA(); b = new ObjectB(); b.prop = a; a.prop = b; a = b = null; ObjectB a b ObjectA: 1 ObjectB: 1
  34. 34. Reference Counting Issues <ul><li>Obviously the circular reference issue is a problem for reference counting, but there are some others too. </li></ul><ul><li>It takes storage to keep the reference count. </li></ul><ul><li>It takes time to keep updating the reference count. </li></ul><ul><li>This is particularly cumbersome and adds overhead to items that are created and destroyed quickly (i.e., items on the stack). </li></ul>Page 3 of 59
  35. 35. Frequent Allocations <ul><li>To address the issue we simply don’t reference count items on the stack. </li></ul><ul><li>That reduces the amount of work significantly, but… </li></ul>Page 3 of 59
  36. 36. Missing Stack Count <ul><li>If x doesn’t count as a reference to ObjectA, then how many references does ObjectA have? What would happen if ObjectA disappeared before the trace() statement? </li></ul>Stack Memory method x Page 3 of 59 ObjectA a = new ObjectA(); var x = a; a = null; trace( x.someProp ); ObjectA: 0
  37. 37. Zero Count Table <ul><li>Instead of immediately destroying ObjectA when its reference count reaches 0, it is added to a Zero Count Table (ZCT). </li></ul>Page 3 of 59 a = new ObjectA(); var x = a; a = null; trace( x ); ObjectA: 0 Zero Count Table Stack Memory method x ObjectA
  38. 38. Zero Count Table <ul><li>When the ZCT is full, it can be reaped to destroy objects. If an object made it to the ZCT, then the only reference that could remain are on the stack. So, the stack is scanned. Any objects without a stack reference are destroyed. </li></ul>Page 3 of 59 ObjectA Zero Count Table ObjectB ObjectC Stack Memory method x
  39. 39. Back to Circles <ul><li>The combination of those techniques are called Deferred Reference Counting. </li></ul><ul><li>Which is great, but we still have circular reference problems. This is a huge problem as we can never collect certain objects (think about parent/child relationships of XML). </li></ul><ul><li>So, we need another technique to handle these cases. </li></ul>Page 3 of 59
  40. 40. Mark and Sweep <ul><li>The other technique used by the Flash Player garbage collector is called mark and sweep. </li></ul><ul><li>Each managed object in the system has an extra bit called a mark bit. </li></ul>Page 3 of 59
  41. 41. Marking <ul><li>You start with a tree of Objects. In this case Object A is a GC root. </li></ul>Page 3 of 59 Object A Object Object Object Object Object Object Object Object Object Object Object
  42. 42. Marking <ul><li>From Object A all paths are followed, marking each child that is encountered. </li></ul>Page 3 of 59 Object A Object Object Object Object Object Object Object Object Object Object Object
  43. 43. Remainder <ul><li>Anything that is not marked is not reachable. That means it can be discarded. </li></ul>Page 3 of 59 Object A Object Object Object Object Object Object Object Object Object Object Object
  44. 44. Tangent – Weak References <ul><li>Many of you may have heard of weak references and have heard advice such as: </li></ul><ul><li>“ When adding an event listener to an object, you should make the reference weak” </li></ul><ul><li>myObj.addEventListener(type, listener, </li></ul><ul><li>useCapture, priority, useWeakReference ); </li></ul><ul><li>What does this argument actually do? </li></ul>Page 3 of 59
  45. 45. Tangent – Weak References <ul><li>Additionally, the Dictionary class can be constructed to use weak keys. </li></ul><ul><li>var d = new Dictionary( weakKeys:Boolean = false ); </li></ul><ul><li>d[ someObject ] = 5; </li></ul><ul><li>Note, only the keys can be made weak in the Dictionary. </li></ul><ul><li>So, again, what does this argument actually do? </li></ul>Page 3 of 59
  46. 46. Weak Reference <ul><li>I like to think of it as adding a path that cannot be travelled by the marking. If the object has no other references, it can be collected. </li></ul>Page 3 of 59 Object A Object Object Object Object Object Object Object Object Object Object
  47. 47. Tangent – Weak References <ul><li>So, should you always use weak references? </li></ul><ul><li>Absolutely not. </li></ul><ul><li>Understand when and where these are needed, then use them appropriately. </li></ul><ul><li>What are some appropriate times? What are the alternatives? </li></ul>Page 3 of 59
  48. 48. Back on Track <ul><li>For some strange reason, people don’t like their application to pause noticeably while garbage collection runs. </li></ul><ul><li>Unfortunately, the process of walking an entire application and marking all of the objects takes serious time. </li></ul><ul><li>So, how do you do that and not make things pause? Well, don’t do it all at once, of course. </li></ul>Page 3 of 59
  49. 49. Work Queue <ul><li>So, we make a work queue. We push all of the roots onto the work queue and we process. When the queue is empty we are done. </li></ul>Page 3 of 59 Work Queue Object A Object B
  50. 50. Hello Complexity <ul><li>The problem with not doing all the marking at once introduces serious complexity. Imagine if your code adds child to parent after parent has already been marked. Child would never be marked and eventually collected. </li></ul>Page 3 of 59 Object A Parent Object Object Child
  51. 51. Tri-Color <ul><li>To handle the complexity of managing this type of garbage collection marking incrementally, Flash Player uses something called the tri-color algorithm. </li></ul><ul><li>Every object has 3 possible states: </li></ul><ul><li> Black objects are marked and no longer in the work queue. </li></ul><ul><li> Gray objects are in the queue, but not yet marked. </li></ul><ul><li> White objects are not in the queue and not marked. </li></ul>Page 3 of 59
  52. 52. Work Queue Start <ul><li>We start by putting all the roots on the queue. This makes them gray. </li></ul>Page 3 of 59 Work Queue Object A Object B
  53. 53. Queue Progress <ul><li>As the queue is processed, gray becomes black, white becomes gray. </li></ul>Page 3 of 59 Work Queue Object B
  54. 54. New Addition <ul><li>In most cases, new objects can be added at will, but we have a problem when a white object is added to a black object. It will never be marked. </li></ul>Page 3 of 59 Work Queue Object B O1 O2 O3 O4 Object B Object Object Object Object
  55. 55. Added to the Queue <ul><li>So, whenever a white object is added to black, it immediately gets added to the work queue. If you are interested, this is accomplished via a write barrier. </li></ul>Page 3 of 59 Work Queue Object B O1 O2 O1 O2 O3 O4 Object B Object Object Object Object
  56. 56. Being Conservative <ul><li>So far that explains most of the phrase conservative mark and sweep garbage collector with deferred reference counting. </li></ul><ul><li>What’s missing is the explanation of conservative. </li></ul><ul><li>In this case conservative means we might not free something that we can’t definitively tell should be free. </li></ul>Page 3 of 59
  57. 57. Pointer or Integer <ul><li>When the garbage collector comes across certain values it is difficult to tell if the value is a memory address (a pointer to an object) or just a numeric value. So, GC will not collect an object that *may* be referenced. </li></ul><ul><li>For example: </li></ul><ul><li>0x00800A30 – Could represent 8,391,216 </li></ul><ul><li>0x00801F37 – May represent an object in memory </li></ul><ul><li>0x00802FFE – Some bytes in a bitmap </li></ul>Page 3 of 59
  58. 58. Minor Leaks <ul><li>This can mean that, on occasion, an object may not be collected because there is an integer somewhere that may, possibly, be interpreted as pointing to it. </li></ul><ul><li>GC would rather take that risk than remove something you could be using. </li></ul><ul><li>This type of leak is minimal and not likely to cause much of an issue. The item to note is that we don’t know exactly where objects in memory may exist, we have to guess. More on that later. </li></ul>Page 3 of 59
  59. 59. Moving On <ul><li>So, now you have a good sense of what GC is doing to decide when your memory is collected. </li></ul><ul><li>The two remaining questions that always come up are: </li></ul><ul><li>Can I control GC? </li></ul><ul><li>Since my system memory didn’t go down when I did X, Y or Z, I must have a leak, right? </li></ul>Page 3 of 59
  60. 60. Controlling GC <ul><li>Leaving aside hacky approaches for the moment, you have some minimal ability to influence and control GC (depending on your runtime version). </li></ul><ul><li>class System { </li></ul><ul><li>public static function gc():void; </li></ul><ul><li>} </li></ul><ul><li>In Flash Player this does nothing. Absolutely nothing. </li></ul><ul><li>In AIR this forces either a mark or sweep to run. Not immediately, but later this frame. </li></ul>Page 3 of 59
  61. 61. Imminence <ul><li>As you know, it takes a while for to mark all of the objects in the system. This is done incrementally. </li></ul><ul><li>It also takes time to reclaim that memory. Doing so synchronously can make your application pause. </li></ul><ul><li>The term imminence is a measurement of how far the collector is through marking all of the objects, and hence, how close it is to creating that pause. </li></ul>Page 3 of 59 Pause Marking 0 Imminence Increasing 1
  62. 62. Something Incubating <ul><li>The Flash Player Incubator introduces a new function: </li></ul><ul><li>class System { </li></ul><ul><li>public static function pauseForGCIfCollectionImminent (imminence:Number=.75):void; </li></ul><ul><li>} </li></ul><ul><li>The value of imminence is clamped between .25 and 1. </li></ul><ul><li>Using this API you can advise Flash Player about good times to collect. </li></ul>Page 3 of 59
  63. 63. Pause Now <ul><li>When you call pauseForGCIfCollectionImminent() the value you pass is compared against the collectors current imminence. </li></ul><ul><li>Effectively, if the collector’s imminence is greater than the value you provide, the collector will finish marking and sweeping synchronously. </li></ul><ul><li>This will result in an application pause. </li></ul>Page 3 of 59 Pause Marking 0 Imminence Increasing 1
  64. 64. Wait, pause now? <ul><li>Why in the world would you want to pause? </li></ul><ul><li>The player is going to pause at some point. Using this API you can effectively indicate how much of a pause you are willing to tolerate at that moment. </li></ul><ul><li>Low value means: I have lots of time and think I should GC now. I am willing to tolerate a long pause now. </li></ul><ul><li>Higher value means: I have a little time and think I should GC now. I am willing to tolerate a shorter pause. </li></ul><ul><li>Note: In both cases you are asking for GC if it can be </li></ul><ul><li>done within your criteria. </li></ul>Page 3 of 59
  65. 65. Advice Examples <ul><li>A bad time to collect: </li></ul><ul><li>function doIt() { </li></ul><ul><li>startComplexAnimation(); </li></ul><ul><li>System.pauseForGCIfCollectionImminent( .25 ); </li></ul><ul><li>} </li></ul><ul><li>A good time to collect: </li></ul><ul><li>function doIt() { </li></ul><ul><li>complexDataProvider = null; </li></ul><ul><li>asyncCallToGetMoreData(); </li></ul><ul><li>System.pauseForGCIfCollectionImminent( .25 ); </li></ul><ul><li>} </li></ul>Page 3 of 59
  66. 66. Giving Back <ul><li>Way back in the beginning of this journey, we talked about how the GCHeap allocates megabytes and gives 4k chunks of memory to the GC so that new objects can be allocated. </li></ul>Page 3 of 59 System Memory 4k 4k 4k GCHeap GC
  67. 67. <ul><li>Objects are allocated on those pages and some are collected. Over time we get fragmentation. </li></ul>Fragmentation Page 3 of 59 Object Object Object Pages are allocated and space for objects allocated. Object Object Object Object Object Object Some objects collected, some new ones created Object Object Object Net result: Even though we did collect objects, we cant release any pages. Object Object Time
  68. 68. <ul><li>That fragmentation makes it almost impossible to judge if you have memory leaks by looking at system memory alone. </li></ul><ul><li>It’s why tools like memory profilers are so important. They are the only reliable way to gain insight into your situation from outside of the player. </li></ul>Fragmentation Page 3 of 59
  69. 69. <ul><li>Now, I would like to wildly speculate. </li></ul><ul><li>Well, okay, perhaps not wildly. If one were to pay attention to the Tamarin project, one might see a lot of work being committed by Adobe around GC. </li></ul><ul><li>One might conclude that this gives some insight into where player GC is going. Yes, one just might. </li></ul>Pure Speculation Page 3 of 59
  70. 70. <ul><li>Going back to fragmentation: why don’t we just collapse all of these objects into a single page and free the others? </li></ul>Fragmentation Page 3 of 59 Object Object Object Pages are allocated and space for objects allocated. Object Object Object Object Object Object Some objects collected, some new ones created Object Object Objects are moved into a single page. Other pages could be freed. Time Object Object Object
  71. 71. <ul><li>Well, it goes back to the point that Flash doesn’t really know where references to objects are. Back when we discussed conservative, we showed this example: </li></ul><ul><li>If you don’t know where your references are, it is impossible to move them around. </li></ul><ul><li>0x00800A30 – Could represent 8,391,216 </li></ul><ul><li>0x00801F37 – May represent an object in memory </li></ul><ul><li>0x00802FFE – Some bytes in a bitmap </li></ul>Objects, where? Page 3 of 59
  72. 72. <ul><li>There is a solution to this problem, though. We could keep better track of what is actually a pointer and what isn’t. </li></ul><ul><li>If we did that we might gain a few advantages. </li></ul><ul><li>No more guessing on what’s a pointer and not — possible conservative leaks disappear. </li></ul><ul><li>We can likely be a bit faster doing our overall GC. </li></ul><ul><li>If we wanted to move an object, we could find and update all references to it. </li></ul>Exact Tracing Page 3 of 59
  73. 73. <ul><li>And, for fun, here is a bunch of information about implementing exact tracing in Tamarin: </li></ul><ul><li>Exact tracing manual: </li></ul><ul><li>http://hg.mozilla.org/tamarin-redux/raw-file/tip/doc/mmgc/exactgc-manual.html </li></ul><ul><li>Exact GC cookbook: </li></ul><ul><li>http://hg.mozilla.org/tamarin-redux/raw-file/tip/doc/mmgc/exactgc-cookbook.html </li></ul><ul><li>Exact tracing profiler </li></ul><ul><li>http://hg.mozilla.org/tamarin-redux/raw-file/tip/doc/mmgc/exactgc-profilers.html </li></ul>Exact Tracing Page 3 of 59
  74. 74. <ul><li>So, speculating just a bit more, why else might we want to be able to move objects? </li></ul><ul><li>Well, it turns out if we can move objects we can implement other types of garbage collection, some of which can be very, very efficient. </li></ul><ul><li>Enter the idea of ephemeral garbage collection. </li></ul>Why Else? Page 3 of 59
  75. 75. <ul><li>Ephemeral, also known as generational, garbage collection is all based on a simple hypothesis: </li></ul><ul><li>The objects that were created most recently are the ones that are most likely to have a short life span and hence need collection sooner. </li></ul><ul><li>Generational garbage collectors use a heuristic approach. In this way it optimizes the work it is doing to have the most impact. </li></ul>Generational Page 3 of 59
  76. 76. <ul><li>In a generational garbage collection scheme, you keep objects in separate areas depending on how long they have been around. </li></ul>Generational Page 3 of 59 Object Object Object New objects live in this region. GC checks this region often for reaping. Object Object Object Object Object The oldest objects in the system are checked infrequently Object Object Object Object Age
  77. 77. <ul><li>When the youngest region is full, we promote objects still referenced in older memory and reuse the youngest area. </li></ul>Generational Page 3 of 59 Object Object Object This region is continually reused Object Object Object Object Object Object Objects are copied if they are referenced from older memory Object The oldest objects change infrequently Object Object Object Object Object Movement
  78. 78. <ul><li>If using generation garbage collection becomes a reality, then the need for reference counted objects and the overhead that goes with that scheme could be eliminated. </li></ul><ul><li>This means less operations for GC, taking less time, requiring less processor, in a smaller memory footprint, yielding more performant applications. </li></ul><ul><li>Remember, just speculation. </li></ul>Reference Count No More Page 3 of 59
  79. 79. Contact Information Michael Labriola http://twitter.com/mlabriola Page 59 of 59

×