The Stack and Heap

In this lab, you will work with reference variables and the NetBeans debugger.

Storage of Variables

Because variables are used so frequently, they need to be in a place where they can be quickly accessed. The stack provides this place. Each local variable, whether it is a primitive data type or a reference variable, is stored on the stack. When you use a variable's name, the computer quickly locates that variable in memory and retrieves its value.

Physically, the stack is nothing more than a big block of memory. The system handles all the details of managing its size so you don't have to worry about it.

Variable Passing

When you call a method, that method is given a portion of memory at the top of the stack to store its local variables and parameters. Because each method uses its own portion of the stack, we know that one method cannot modify the local variables of another methods.

When a method returns (or finishes running), the portion of memory on top of the stack used by that method is freed by the system. In other words, that method's variables no longer exist in memory. The following Stack N' Heap demonstrates this:


Stack N' Heap What's This? The Stack N' Heap simulates a trace program. It shows the code being executed, the contents of the stack, and the contents of the heap. To move through the code, use the >> button. This will take you one step through the code. To go back one step, use the << button.

Primative variables are shown in the stack with their names on the left side and values on the right. Reference variables do not have any value on the right, but instead have a yellow line drawn to show which object in the heap it points to. Reference variables with a NULL value don't show anything on the right.
Code
{
int myVar = 5;
dosomething ( );
System.out.println( myVar );
}

public void dosomething ( ) {
int myVar = 18;
System.out.println( myVar );
}
Stack
Heap
Temporary

Because methods do not share memory, the only way methods can share information is via return values and parameters. A method can return information to the method that called it using a return value. A method can send information to the method it is calling by giving values to that method's parameters. The following Stack N' Heap demonstrates the use of return values.


Stack N' Heap What's This? The Stack N' Heap simulates a trace program. It shows the code being executed, the contents of the stack, and the contents of the heap. To move through the code, use the >> button. This will take you one step through the code. To go back one step, use the << button.

Primative variables are shown in the stack with their names on the left side and values on the right. Reference variables do not have any value on the right, but instead have a yellow line drawn to show which object in the heap it points to. Reference variables with a NULL value don't show anything on the right.
Code
{
int myVar = 5;
myVar = dosomething2 ( myVar );
System.out.println( myVar );
}

public int dosomething2 ( int temp ) {
return ( temp + 15 );
}
Stack
Heap
Temporary
Storage of Objects

All objects are stored on the heap. The system cannot find an object once it is stored on the heap unless it knows its address; an object addresses are stored in reference variables. Although objects that are not referenced by a reference variable are useless, they still take up space in memory. To reclaim this space, a procedure called garbage collection is run. This process scans the heap to find objects that can be removed. The system handles this automatically; you needn't worry about it.

Passing Variables

As mentioned above, a method can send information to a called method by giving values to that method's parameters. A method's parameters are declared in the parenthesis immediately following the method's name. The syntax for declaring a parameter is very simple, it is identical to declaring a variable. For instance: the method header public void dosomething (int param1, String param2) begin a method named dosomething that has two parameters: an integer named param1, and a String reference variable named param2. In order to call this method, you must provide an initial value for each of these parameters, such as dosomething(5, "This is a test");. (Note that a comma separates the two expressions supplied for the parameters.) The values "passed" to the method when you call it become the initial values of that method's parameters.

Passing Primitive Data Types

When you call a method you must specify the initial values of its parameters; these values can be changed as the method runs. Using the assignment operator, you can change the value stored in a parameter, but this will have no effect on the variable stored in the calling method:


Stack N' Heap What's This? The Stack N' Heap simulates a trace program. It shows the code being executed, the contents of the stack, and the contents of the heap. To move through the code, use the >> button. This will take you one step through the code. To go back one step, use the << button.

Primative variables are shown in the stack with their names on the left side and values on the right. Reference variables do not have any value on the right, but instead have a yellow line drawn to show which object in the heap it points to. Reference variables with a NULL value don't show anything on the right.
Code
{
int myVar = 5;
dosomething3 ( myVar );
}

public void dosomething3 ( int temp ) {
temp = temp + 15;
}
Stack
Heap
Temporary

Passing Reference Variables

Remember that reference variables store addresses. When a parameter is a reference variable, it must be given an object's address as its initial value. You can use the assignment operator to change the address stored in a reference parameter. You can also use the address stored in the reference parameter to change the instance variables of the object to which it refers. These changes will exist after the method stops running. The following Stack N' Heap illustrates this:


Stack N' Heap What's This? The Stack N' Heap simulates a trace program. It shows the code being executed, the contents of the stack, and the contents of the heap. To move through the code, use the >> button. This will take you one step through the code. To go back one step, use the << button.

Primative variables are shown in the stack with their names on the left side and values on the right. Reference variables do not have any value on the right, but instead have a yellow line drawn to show which object in the heap it points to. Reference variables with a NULL value don't show anything on the right.
Code
{
intHolder myVar = new intHolder ( 5 );
dosomething4 ( myVar );
System.out.println( myVar.getInt() );
}

public void dosomething4 ( intHolder temp ) {
temp.setInt ( 20 );
}
Stack
Heap
Temporary
References
To Get Started ...

Download the jar file: Stack.jar to your csci/201 directory, unjar the file (Help), create a new NetBeans project called Stack, and mount the Stack directory created when you unjarred the archive file (Help). Your directory structure should look something like the picture below:
After the jar

Your Assignment ...

Reference Variables

The file Teacher.java defines a simple class that represents a Teacher, an object with a name, a picture, and a rating. The file References1.java contains a program that instantiates two Teacher objects and then makes some modifications to the objects and their references. Your job is to complete that program as described in the comments in References1.java. There are three modifications that you are asked to make and there is a checkoff below for each of these three modifications.

Setting the working directory

However, this is one small task before we get started. Some of the methods and constructors of Teacher must be passed filenames containing GIF images.

This prevents a slight problem for the Java system because it must determine the directory containing the GIF image. NetBeans allows you to set your program's working directory to handle this problem, but this takes a bit of work. First, go into the Filesystems pane of the Explorer panel and right-click on the Teacher icon; select Properties from the pop-up window. Now select the Execution tab at the bottom left of the Properties window.

Next, make sure that Executor is set to External Execution and press on External Execution. This should cause a box with three little dots to appear just to the left of External Execution. Now, double click on the box with three dots.
Selecting the Executor

The Executor window should pop-up. Click on the Expert tab in the right panel. You should now see a table with a cell containing Working Directory in the lower left corner. Its partner cell in the lower right corner is blank. Click on the blank cell and be rewarded with another box of triple dot. Finally, click on the triple dots. Now you have the Working Directory pop-up which you can use to set the directory Java uses for opening files with relative filenames. Set this directory to your csci/201/Stack subdirectory.
External Execution selections

If we weren't interested in debugging, we'd be done. However, we must now set the working directory for the debugger. So do back to the Execution panel and this time select the triple dots for Debugger rather than Executor. pop-up.
Selecting the Debugger

Now set the Working Directory in the Debugger to also be class/201/Stack.
Debugger selections

Instructor Checkoff ...

Show your lab instructor your code for swapping reference variables along with the displays of both the original and the "swapped" teachers.

Instructor Checkoff ...

Show your lab instructor your code for swapping the objects' names along with displays of the teachers both before and after "swapping" their names. (Be sure to comment out all other displays.)

Instructor Checkoff ...

Checkoff for swapping object names in Reference1.java

Show your lab instructor your code for swapping the objects' ratings along with displays of the teachers both before and after "swapping" their ratings. (Be sure to comment out all other displays.)

Debugging with NetBeans
Your Assignment ...

More on references

Open References2.java and compile and run the program. Now that you've run the program and seen the output, study the code and try to understand what is happening. Wouldn't it be helpful to see the Java code be executed a line at a time? This is something we can do with the debugger.

A debugger can step through your program code one line at a time while you examine the values of your program variables. You can also set a breakpoint on a line of code of your program. Your program executes normally until it reaches the breakpoint at which point the program is halted so that you can examine its variables.

Setting a breakpoint

Let's start by setting a breakpoint in the Reference2 class. Do this by placing your cursor anywhere within the line that says:


      System.out.println ("Enter a teacher rating...");

Next right click while the cursor remains on the line of Java code. You should see a new pulldown menu. Select Toggle Breakpoint from the menu. A pink rectangle should now surround the selected line.
Selected line for debugging

Setting the debugging main class

Because we have more than one class with a main method, we're going to choose a specific main class for the debugging project. This isn't stickly necessary, but it will decrease your chances of going astray during this lab.

Make this choice by going into the Explorer panel and right clicking on the Reference2 icon. In the displayed menu select Tools and then Set as Project Main Class.
Setting Project Main class

Starting the debugger

You can start debugging from the Project pull-down menu by selecting Debug Project. or you can just select the Run in Debugger button, Run in debugger icon.

Your program starts, screen flash, and soon you should see that the line with the breakpoint now has a green background and is the target of a little green arrow. Your breakpoint has been reached.
At the breakpoint

The debugger window

Be sure that the left panel is displaying the Debugger Window. If not, select the Debugging tab.

At the top of the Debugger Window is a line of nine icons. Start by turning off all of these nine selections, so that your icons display as below. These icons control your view of your program and its variables. We're going to experiement with these controls. In the following few paragraphs turn on and off each icon to see its effect. By the way, it is possible to have several icons selected simultaneously.
Debugger windows selections

Debugger view controls

Sessions The first icon shows the status of your debugging sessions. If should show that your References2 session has been stopped on a breakpoint. It is unlikely that you will ever intentionally have more than one active debugging session while a student in this course.

Threads The second icon shows the status of your program's threads. It is possible to have more than one Java interpreter simultaneously executing the methods of your program. In fact, multi-threaded applications are required for interesting multi-media applications and you have undoubtedly encountered many on the web. Right now, your application may appear to have only one thread, but push down on those expanders, and you'll see more.
Threads in debug window

Call Stack The third icon shows your call stack. This can be used to determine the series of method calls that were made to reach the breakpoint.

Local Variables The fourth icon displays the local variables of a active method invocation. It is possible, though rarely advisable, to change the value of a variable in this display. Because an object may be passed between method, it may appear in many different method invocations.

All in One The debugger may be working on several sessions. Each session may be executed by several threads, each with its own call stack. Each call stack may have several method invocations, each with its own set of local variables. The fifth icon, called All in One, puts this entire hierarchy into a single display. Press the expanders in the All in One window to descend to the depths of your Java program.
All in One window

Watches The sixth icon controls watches. A watch is a variable the debugger is actively tracking. This used with a programmer thinks a particular variable is causing problems and requires special attention. The value of that variable is displayed in the watch list.

Classes The seventh icon allows you to lists the fields, constructors, and methods of your active classes. Many classes are within packages and you must descent through the class hierarchy to uncover them. Press the Classes icon. Notice that the class Teacher is not displayed. That's because your program has yet to instantiate an object of class Teacher.

Breakpoints The eighth icon provides a quick list of breakpoints.

Properties The ninth icon is for properties, a mechanism for internationalizing the text displayed by a Java application. You won't use them here.

Stepping through the code

When you reach a breakpoint, you can start stepping through the code. For each line of code, you can either:

Stepping through the References2

Presumably your debugger is still waiting at the breakpoint. Go into the Local Variables view where you should see nothing put a single variable args.

Now lets do some debugging. Use the Step Over button, or F8 key, to execute the current line of code and advance to the next. Notice the prompt for input in the output window. Notice also that you can't advance until you provide that input. Enter a value for rating and see its value in the local variables display.

Contine to step over lines of code until the first call to the zeroRating() method is highlighted. By now, you should have a teacher reference variable in the local variables display. Click the expander to teacher to view its instance variables.
Expanding local variables
Note that some of the instance variables are also references to objects that can be viewed. Explore all reference variables and make sure that you understand what you see.

Now use the Step Into button, or the F7 key, to step into the zeroRating() method. Display both the call stack and local variables windows and switch between the two sets of local variables by choosing between the two frames of the call stack. You choose a frame by double-clicking on that frame in the call stack.
zeroRating stack frame zeroRating stack frame

Instructor Checkoff ...

Advance to the "}" marking the end of the zeroRating() method.

Show your lab instructor the variables in both zeroRating() and main(). Explain why the value of rating in main() is not changed by the call to zeroRating().

Instructor Checkoff ...

Advance until the second call to zeroRating() is highlighted, and then step in to zeroRating(). Again, observe the call stack and local variables display. Click the expander to view the object referenced by the argument inputTeacher. Advance to the "}" marking the end of this zeroRating() method.

Show your lab instructor the variables in both zeroRating() and main(). Explain why the Teacher object created in main() is changed by the call to zeroRating().