Chapter 14. The Stack, the Heap, and the Garbage Collector

In this chapter, we will make a good start with the next project, an authentic looking, clone of the classic Snake game.

It is also the time that we understood a little better what is going on underneath the Android hood. We constantly refer to 'references' but what exactly is a reference and how does it affect how we build games?

  • Managing memory with the Stack, the Heap, and the Garbage Collector
  • Introduction to the Snake Game
  • Getting started with the Snake game project

Let's start with the theory part.

Managing and understanding memory

In Chapter 4, Structuring Code with Java Methods we learned a bit about references. Here is a quick recap

Note

… known as a reference type. They quite simply refer to a place in memory where storage of the variable begins but the reference type itself does not define a specific amount of memory used. The reason for this is straightforward.

We don't always know how much data will be needed to be stored in it until the program is executed.

We can think of Strings and other reference types as continually expanding and contracting storage boxes. So, won't one of these String reference types bump into another variable eventually?

As we are thinking about the device's memory as a huge warehouse full of racks of labeled storage boxes, then you can think of the DVM as a super-efficient forklift truck driver that puts the distinct types of storage boxes in the most appropriate places.

And if it becomes necessary, the DVM will quickly move stuff around in a fraction of a second to avoid collisions. Also, when appropriate, Dalvik, the forklift driver, will even throw out (delete) unwanted storage boxes. This happens at the same time as constantly unloading new storage boxes of all types and placing them in the best place, for that type of variable…

In the same chapter, we learned that arrays and objects are also references but at the time we knew none of the details we currently know about arrays and objects. Now that we do we can dig a little deeper.

Dalvik keeps reference variables in a different part of the warehouse to the primitive variables.

Variables revisited

We know that a reference is a memory location, but we need to understand a bit more.

You probably remember, right back to the first game project, we kept changing where we declared our variables? First, we declared some in onCreate and others just below the class declaration. When we moved them to just below the class declaration, we were making them member or instance variables.

And because we didn't specify the access, they were default access and visible to the whole class. And as everything took place in the one class we could access them everywhere. But why couldn't we do that when they were declared in onCreate? We learned that this phenomenon is known as scope and that variables, depending upon their access specifier (for members) or which method they are declared in (for local).

But why? Is this some artificial construct? In fact, it is a symptom of the way that processors and memory work and interact. We won't go into depth about such things now but a further explanation about when and how we can access different variables is probably going to be useful.

The stack and the heap

The Virtual Machine inside every Android device takes care of memory allocation to our games. In addition, it stores different types of variables in different places.

Variables that we declare and initialize in methods are stored on the area of memory known as the stack. We can stick to our warehouse analogy when talking about the stack- almost. We already know how we can manipulate the stack.

Let's talk about the heap and what is stored there. All reference type objects which includes objects (of classes) and arrays are stored on the heap. Think of the heap as a separate area of the same warehouse. The heap has lots of floor space for oddly shaped objects, racks for smaller objects, lots of long rows with smaller sized cubby holes for arrays and so on. This is where our objects are stored. The problem is, we have no direct access to the heap. Let's look again at what exactly a reference variable is.

It is a variable that we refer to and use via a reference. A reference can be loosely but usefully defined as an address or location. The reference (address or location) of the object is on the stack. So, when we use the dot operator, we are asking Dalvik to perform a task at a specific location as stored in the reference.

Tip

Reference variables are just that— a reference. A way to access and manipulate the object (variables, methods) but they are not the actual variables itself. An analogy might be that primitives are right there (on the stack) but references are an address and we say what to do at the address. In this analogy, all addresses are on the heap.

Why oh why would we ever want a system like this? Just give me my objects on the stack already. Here is why.

A quick break to throw out the trash

This whole stack and heap thing is forced upon us by computer architecture but Java acts as a middleman and basically helps us manage this memory.

As we have just learned, the Dalvik Virtual Machine keeps track of all our objects for us and stores them in a special area of our warehouse called the heap. Periodically the DVM will scan the stack (the regular racks of our warehouse) and match up references to objects. And any objects (on the heap) it finds without a matching reference, it destroys. Or in Java terminology, it garbage collects.

Think of a very precise and high-tech refuse vehicle driving through the middle of our heap, scanning objects to match up to references. No reference, your garbage now. After all, if an object has no reference variable we can't possibly do anything with it anyway. This system of garbage collection helps our games run more efficiently by freeing up unused memory.

There is a downside, however, the garbage collector takes up processing time and the garbage collector has no knowledge of the time-critical parts of our game like the main game loop. It therefore also has the potential to make our game run poorly.

Now we are aware of this we can make a point of not writing code that is likely to trigger the garbage collector during performance critical parts of the game. So what code exactly triggers the garbage collector. Remember I said this:

Note

Periodically the DVM will scan the stack (the regular racks of our warehouse) and match up references to objects. And any objects (on the heap) it finds without a matching reference, it destroys (frees the memory for reuse). Or in Java terminology, it garbage collects.

If we are calling code like this

someVariable = new SomeClass() 

And then someVariable goes out of scope and is destroyed this is likely to trigger the garbage collector. Even if it doesn't happen at once, it will happen, and we can't decide when. We will keep this in mind as we go ahead with the rest of the projects.

So, variables declared in a method are local, on the stack and only visible within the method they were declared. A member variable is on the heap and can be referenced from anywhere there is a reference to it and the access specification allows it.

Stack and Heap quick summary

Let's take a quick look at what we learned about the Stack and the Heap.

  • Our code doesn't explicitly delete objects. The DVM sends the garbage collector when it thinks it is appropriate. This is usually when there is no active reference to the object.
  • Local variables and methods are on the Stack and the local variables are local to the specific method within which they were declared.
  • Instance/class variables are on the Heap (with their objects) but the reference to the object, the address, is a local variable on the Stack.
  • We control what goes onto the Stack. We can use the objects on the Heap but only by referencing them.
  • The Heap is maintained by the garbage collector.
  • An object is garbage collected when there is no longer a valid reference to it. So, when a reference variable either local or instance is removed from the Stack, then it's related object becomes viable for garbage collection. And when the DVM decides the time is right (usually very promptly), it will free up the RAM memory to avoid running out.

That is all we need to know for now. In fact, you could probably complete this book without knowing any of that but understanding the different areas of memory and the vagaries of the garbage collector from an early point in your Java learning path sets you up to understand what is going on in the code that you write and gives you more understanding.

Now we can make the next game.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.138.120.187