CS112b1
LAB 04 - Stack and A Deeper Look at Java Memory Management

Objectives

  1. Review concepts of stacks and queues
  2. Analyze some code manipulating stacks
  3. Take a deeper look at Java memory management, Garbage Collection
  4. Write some programs ...


Preamble

When you switch from a language with manual memory management, such as C or C++, to a garbage-collected language, your job as a programmer is made much easier by the fact that your objects are automatically reclaimed when you're through with them. It seems almost like magic when you first experience it. It can easily lead to the impression that you don't have to think about memory management, but this isn't quite true...


An implementation of stack abstraction

Code: Stack.java

CAN YOU SPOT THE "MEMORY LEAK" in it?


Lurking Memory Leak

There's nothing obviously wrong with this program. You could test it exhaustively, and it would pass every test with flying colors, but there's a problem lurking. Loosely speaking, the program has a “memory leak,” which can silently manifest itself as reduced performance due to increased garbage collector activity or increased memory footprint. In extreme cases, such memory leaks can cause disk paging and even program failure with an OutOfMemoryError, but such failures are relatively rare.

So where is the memory leak? If a stack grows and then shrinks, the objects that were popped off the stack will not be garbage collected, even if the program using the stack has no more references to them. This is because the stack maintains obsolete references to these objects. An obsolete reference is simply a reference that will never be dereferenced again. In this case, any references outside of the “active portion” of the element array are obsolete. The active portion consists of the elements whose index is less than size.

Memory leaks in garbage collected languages (more properly known as unintentional object retentions) are insidious. If an object reference is unintentionally retained, not only is that object excluded from garbage collection, but so too are any objects referenced by that object, and so on. Even if only a few object references are unintentionally retained, many, many objects may be prevented from being garbage collected, with potentially large effects on performance.


How to fix the problem?

The fix for this sort of problem is simple: Merely null out references once they become obsolete. In the case of our Stack class, the reference to an item becomes obsolete as soon as it's popped off the stack.

public Object pop() {
if (size==0) throw new EmptyStackException();
Object result = elements[--size];
elements[size] = null; // Eliminate obsolete reference
return result;
}


When should you null out a reference?

What aspect of the Stack class makes it susceptible to memory leaks? Simply put, the Stack class manages its own memory. The storage pool consists of the elements of the items array (the object reference cells, not the objects themselves). The elements in the active portion of the array (as defined earlier) are allocated, and those in the remainder of the array are free.

The garbage collector has no way of knowing this; to the garbage collector, all of the object references in the items array are equally valid. Only the programmer knows that the inactive portion of the array is unimportant. The programmer effectively communicates this fact to the garbage collector by manually nulling out array elements as soon as they become part of the inactive portion.

Generally speaking, whenever a class manages its own memory, the programmer should be alert for memory leaks. Whenever an element is freed, any object references contained in the element should be nulled out.


Task

  • Complete the get() and put() methods in an implement of queue abstraction using array. Code: Queue.java
  • Pay attention to potential memory leak and eliminate them
  • gsubmit your code

CS112b1