public class stackheap { /* UNDERSTANDING POINTERS, STACK AND HEAP MEMORY USAGE A rather standard way that memory is used by a program (not just a java program) is to partition it into a RUNTIME STACK segment and a GLOBAL HEAP segment. Let's first talk about the stack. When you call a function such as the 'power' function below, the execution of the function has certain memory requirements. Namely, it requires space to store its local variables. In the case of the power function, it requires memory to store x, n, ax, and pn (4 32-bit ints total 16 bytes). Where are these bytes located? They are placed on the *runtime stack*. Each call to power PUSHES a "stack frame" containing the 16 bytes associated with a set of local copies of x,n,ax,pn. When the function exits (returns), the stack frame is POPPED which means the memory is deallocated. */ int power(int x, int n) // calculates x**n in log(n) steps { int ax = 1, pn = n; while (n>0) { if (n%2==1) ax *= pn; pn = pn*pn; n = n/2; } return ax; }//power /* It's important to understand that a new stack frame is created for each CALL to the function. This is especially important for understanding how recursive functions work. The fact (factorial) function below is recursive. */ int fact(int n) { if (n<2) return 1; else return n*fact(n-1); } /* This function contains only one local variable (n). Each time fact is called, a new frame with n is created and pushed on top of the stack. For example, when we call fact(4), we push a frame with n=4 on the stack. This call in turn calls fact(3), which pushes another n=3 on top of the existing stack frame. This in turn calls fact(2), with another frame with n=2. A final recursive call is made fact(1). At this point, our runtime stack looks like the following: n = 1 ----- n = 2 ----- n = 3 ----- n = 4 Now fact(1) returns 1: this results in the top frame being popped. This means that now "n" is 2. so the n*fact(n-1) here returns 2*1=2: this is what's returned by the call to fact(2). Now the next frame is popped and n is now 3, so n*fact(n-1) is 3*2=6: this is what's returned by fact(3). The frame with n=3 is then popped and now n=4, so the final value of n*fact(n-1) is 4*6 =24. This value is returned by fact(4), and all memory for this computation will be reclaimed by the last pop. As you can see, the more recursive calls are nested on top of each other, the higher the stack will grow. So there could be a stack overflow unless we can guarantee that the growth is within control - such as when it's bounded by a constant or log(n). 'fact' is not a good example of recursion. HEAP AND POINTERS Now the story gets more complicated. Memory for primitive built-in types such as int, double, long, boolean are allocated directly on the stack as shown above. However, everything else in Java is an *Object* and memory is allocated in another part of memory called the *heap*. This includes arrays, Strings, and instances of all classes. In such a situation, what's allocated on the stack is a reference, or pointer, to the heap memory location containing the object: it's basically a memory address. Consider the following, simple, O(n*n) sorting function: */ void swapsort(int[] A) { for(int i=0;i