Stack & heap
Reading: Sierra & Bates, pp. 77, 235–239, 258–265, 663
The Stack and The Heap
- The heap stores all objects, including all arrays, and all class variables (i.e. those declared "static").
- The stack stores all local variables, including all parameters.
When a method is called, the JVM pushes a stack frame onto the stack, and it holds the state of method including which line of code is executing and the values of all local variables and parameters.
STACK | HEAP
|
method call parameters & local variables |
----------------------------------------------|
--- | -------------------
this |.+----------->|item |.| next |X|
SListNode.SListNode --- --- | -------+-----------
obj |.+--------------------------\ |
--- | | |
----------------------------------------------| v v
--- | ------------
obj |.+----------------------->| string |
--- | ------------
SList.insertEnd --- | ^
this |.+--------------------------+---------\
--- | | |
----------------------------------------------| | |
--- | | |
str |.+--------------------------/ v
--- --- | ---------------------
list |.+----------------->|head |X| size | 0 |
--- | ---------------------
SList.main --- | --------- -----------
args |.+------------------------>| . | .-+-->| words |
--- | --+------ -----------
| | -----------
----------------------------------------------| \--->| input |
-----------
All the other stack frames represent methods waiting for the methods above them to return before they can continue executing.
The java.lang library has a method Thread.dumpStack
to print a list of methods on the stack.
Q1: Where do instance variables live? And how JVM makes space?
Parameter Passing
Java always pass by value. The copies reside in the method's stack frame.
When a parameter is a reference, the reference is copied, but the object is shared. It's not pass by reference, it's passing a reference by value.
Binary search
public static final int FAILURE = -1;
private static int bsearch(int[] i, int left, int right, int findMe) {
if (left > right) {
return FAILURE; // Base case 2: subarray of size zero.
}
int mid = (left + right) / 2; // Halfway between left and right.
if (findMe == i[mid]) {
return mid; // Base case 1: success!
} else if (findMe < i[mid]) {
return bsearch(i, left, mid - 1, findMe); // Search left half.
} else {
return bsearch(i, mid + 1, right, findMe); // Search right half.
}
}
public static int bsearch(int[] i, int findMe) {
return bsearch(i, 0, i.length - 1, findMe);
}
Here is what it looks like in the stack frame.
STACK bsearch left [4] |
right [4] findMe [1] |
mid [4] i [.]-+---------\
--------------------------------| |
bsearch left [4] | |
right [6] findMe [1] | |
mid [5] i [.]-+---------|
--------------------------------| |
bsearch left [0] | |
right [6] findMe [1] | |
mid [3] i [.]-+---------|
--------------------------------| |
bsearch findMe [1] i [.]-+---------| -------------------
--------------------------------| \-->| -3 -2 0 0 1 5 5 |
main args [.]-+->[] -------------------
| HEAP
Watch memory usage according to recursion depth. In general, recursion to a depth of roughly log n
(where n is the number of items in a data structure) is safe, whereas n is not. You should use iteration instead of recursion when the recursion will be very deep.
Scope and Recursion
- A local variable is in scope only from the variable declaration down to the innermost closing brace that encloses it. A local variable declared in the initialization part of a "for" loop is in scope only in the loop body. [Block scope]
- Class variables (static fields)
- Fully qualified class variable (
System.out
, rather thanout
) - Instance variables (non-static fields, declared inside a class but not inside a method)
- Fully qualified instance variables
Answers
- Q1: The values of an object's instance variables live inside the object. If it's primitive, JVM knows how much space it needs by its primitive type. For objects, JVM only stores its reference (when it's declared) and the object is made on the heap when the reference variable is assigned a new object.
Important points
- How are different kinds of variables stored?
- How long will they live?
- Then what is the scope for a variable? (differences between "life" and "scope")
Some notes from reading
- An object becomes eligible for GC when its last live reference disappears (either after it goes after the scope permanently, or it's assigned another object, or it is set to null).