0% found this document useful (0 votes)
4 views

10-ObjectsAndMemory

Uploaded by

peachypaimon
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
4 views

10-ObjectsAndMemory

Uploaded by

peachypaimon
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 18

The Art and Science of

Java
An Introduction
ERIC S. ROBERTS to Computer Science
CHAPTER 7

Objects and Memory


Yea, from the table of my memory
I’ll wipe away all trivial fond records.
—William Shakespeare, Hamlet, c. 1600

CS102 @ Özyeğin University

Slides are adapted from the originals available at


http://www-cs-faculty.stanford.edu/~eroberts/books/ArtAndScienceOfJava/

Chapter 7—Objects and Memory


Memory and Addresses
• Every byte inside the primary memory of a machine 0000
0004
0001
is identified by a numeric address. The addresses 0002
0008
000C
0003
begin at 0 and extend up to the number of bytes in 0004
0010

the machine, as shown in the diagram on the right. 0014


0005
0006
0018
001C
0007
• In these slides as well as in the diagrams in the text, 0008
0020

memory addresses appear as four-digit hexadecimal 0024


0009
000A
0028

numbers, which makes addresses easy to recognize. . .


000B
002C

. .
.
• In Java, it is impossible to determine the address of .
FFD0
FFF4
an object. Memory addresses used in the examples FFF5
FFD4

are therefore chosen completely arbitrarily.


FFD8
FFF6
FFF7
FFDC
FFE0
FFF8

• For the rest of this presentation, memory diagrams FFF9


FFE4
FFE8
FFFA
will present four bytes in each of the memory cells, FFFB
FFEC

which means that the address numbers increase by FFF0


FFFC
FFFD
FFF4
four each time. FFF8
FFFE
FFFF
FFFC
The Allocation of Memory to Variables
• When you declare a variable in a program, Java allocates
space for that variable from one of several memory regions.
• One region of memory is reserved for variables that 0000

static
are never created or destroyed as the program runs, data
such as named constants and other class variables.
This information is called static data.
• Whenever you create a new object, Java allocates heap

space from a pool of memory called the heap.


• Each time you call a method, Java allocates a new
block of memory called a stack frame to hold its
local variables. These stack frames come from a
region of memory called the stack.
stack
• In classical architectures, the stack and heap grow
toward each other to maximize the available space. FFFF
Heap-Stack Diagrams
• It is easier to understand how Java works if you have a good
mental model of its use of memory. The text illustrates this
model using heap-stack diagrams, which show the heap on
the left and the stack on the right, separated by a dotted line.
• Whenever your program creates a new object, you need to
add a block of memory to the heap side of the diagram. That
block must be large enough to store the instance variables for
the object, along with some extra space, called overhead, that
is required for any object. Overhead space is indicated in
heap-stack diagrams as a crosshatched box.
• Whenever your program calls a method, you need to create a
new stack frame by adding a block of memory to the stack
side. For method calls, you need to add enough space to store
the local variables for the method, again with some overhead
information that tracks what the program is doing. When a
method returns, Java reclaims the memory in its frame.
Object References
• Internally, Java identifies an object by its address in memory.
That address is called a reference.
• As an example, when Java evaluates the declaration
Rational r1 = new Rational(1, 2);

it allocates heap space for the new Rational object. For this
example, imagine that the object is created at address 1000.
• The local variable r1 is allocated in the current stack frame
and is assigned the value 1000, which identifies the object.
heap stack
1000
num 1 1004
den 2 1008 r1 1000 FFFC

• The next slide traces the execution of the TestRational


program from Chapter 6 using heap-stack model.
A Complete Heap-Stack Trace
public static
public static void
void main(String[]
main(String[] args) args) {{
Rational aa == new
Rational new Rational(1,
Rational(1, 2); 2);
public Rational add(Rational
Rational bb == new
new Rational(1,
Rational(1, 3);r) {
3); 36
5
Rational
Rational cc == new
new Rational(1,
Rational(1, 1 6); 3 1 2
Rational 6);
return new
Rational sumRational( this.num * r.den + r.num * this.den ,
Rational sum == a.add(b).add(c);
a.add(b).add(c);
println(a ++ "" ++ "" ++ bb +this.den
println(a + "" ++ "" ++*ccr.den );
++ "" == "" ++ sum);
sum);
}}} 36
6

heap
heap stack
stack TestRational
TestRational
1000
1000
1/2 ++ 1/3
1/2 1/3 ++ 1/6
1/6 == 11
num
num 11 1004
1004
den
den 22 1008
1008 All objects are created
100C
100C in the heap.
num
num 11 1010
1010
den
den 33 1014
1014
1018
1018 This object is a temporary value
num
num 11 101C
101C used only during
r the100C
calculation.
1018 FFE0 This stack frame is created
den
den 66 1020
1020 this 1000
1024 FFE4 for the add method.
1024
1024 FFE8
num
num 55 1028
1028 sum
sum 1030
1030 FFEC
FFEC
den
den 66 102C
102C cc 1018
1018 FFF0
FFF0 This stack frame is created
1030
1030 bb 100C
100C FFF4
FFF4 for the main method.
num
num 11 1034
1034 aa 1000
1000 FFF8
FFF8
den
den 11 1038
1038 FFFC
FFFC skip simulation
The Pointer Model
• The heap-stack diagram at the lower left shows the state of
memory at the end of the run method from TestRational.
• The diagram at the lower right shows exactly the same state
using arrows instead of numeric addresses. This style of
diagram is said to use the pointer model.
heap stack heap stack
1000
num 1 1004 num 1
den 2 1008 den 2
100C
num 1 1010 num 1
den 3 1014 den 3
1018
num 1 101C num 1
den 6 1020 den 6
1024
num 5 1028 sum 1030 FFEC num 5 sum
den 6 102C c 1018 FFF0 den 6 c
1030 b 100C FFF4 b
num 1 1034 a 1000 FFF8 num 1 a
den 1 1038 FFFC den 1
Addresses vs. Pointers
• The two heap-stack diagram formats—the address model and
the pointer model—describe exactly the same memory state.
The models, however, emphasize different things:
– The address model makes it clear that references have numeric values.
– The pointer model emphasizes the relationship between the reference
and the object and makes the diagram easier to follow.
heap stack heap stack
1000
num 1 1004 num 1
den 2 1008 den 2
100C
num 1 1010 num 1
den 3 1014 den 3
1018
num 1 101C num 1
den 6 1020 den 6
1024
num 5 1028 sum 1030 FFEC num 5 sum
den 6 102C c 1018 FFF0 den 6 c
1030 b 100C FFF4 b
num 1 1034 a 1000 FFF8 num 1 a
den 1 1038 FFFC den 1
Garbage Collection
• One fact that the pointer model makes clear in this diagram is
that there are no longer any references to the Rational value
5/6. That value has now become garbage.
• From time to time, Java runs through the heap and reclaims
any garbage. This process is called garbage collection.
heap stack

num 1
den 2

num 1
den 3

num 1
This object was used to hold a temporary
den 6
result and is no longer accessible.
num 5 sum
den 6 c
b
num 1 a
den 1
Exercise: Stack-Heap Diagrams
Suppose that the classes Point and Line are defined as follows:
public class Point { public class Line {
public Point(int x, int y) { public Line(Point p1,
cx = x; Point p2) {
cy = y; start = p1;
} finish = p2;
}
. . . other methods appear here . . .
. . . other methods appear here . . .
private int cx;
private int cy; private Point start;
} private Point finish;
}

Draw a heap-stack diagram showing the state of memory just


before the following main method returns.
public static void main(String[] args) {
Point p1 = new Point(0, 0);
Point p2 = new Point(200, 200);
Line line = new Line(p1, p2);
}
Solution: Stack-Heap Diagrams
Address Model Pointer Model

heap stack heap stack


1000
cx 0 1004 cx 0
cy 0 1008 cy 0
100C
cx 200 1010 cx 200
cy 200 1014 line 1018 FFF0 cy 200 line
1018 p2 100C FFF4 p2
start 1000 101C p1 1000 FFF8 start p1
finish 100C 1020 FFFC finish
Primitive Types vs. Objects
• At first glance, Java’s rules for passing objects as arguments
seem to differ from the rules Java uses with arguments that
are primitive types.
• When you pass an argument of a primitive type to a method,
Java copies the value of the argument into the parameter
variable. As a result, changes to the parameter variable have
no effect on the argument.
• When you pass an object as an argument, there seems to be
some form of sharing going on. Although changing the
parameter variable itself has no effect, any changes that you
make to the instance variables inside an object—usually by
calling setters—have a permanent effect on the object.
• Stack-heap diagrams make the reason for this seeming
asymmetry clear. When you pass an object to a method, Java
copies the reference but not the object itself.
Primitive Types vs. Objects
Primitive Types vs. Objects

OUTPUT:
Linking Objects Together
• Although most examples of this technique are beyond the
scope of a first course, references are particularly important in
computer science because they make it possible to represent
the relationship among objects by linking them together in
various ways.
• One common example is called a linked list, in which each
object in a sequence contains a reference to the one that
follows it:

data data data data


link link link link null

• Java marks the end of linked list using the constant null,
which signifies a reference that does not actually point to an
actual object. The value null has several other uses, as you
will discover in the chapters that follow.
The Beacons of Gondor
For answer Gandalf cried aloud to his horse. “On, Shadowfax!
We must hasten. Time is short. See! The beacons of Gondor are
alight, calling for aid. War is kindled. See, there is the fire on
Amon Dîn, and flame on Eilenach; and there they go speeding
west: Nardol, Erelas, Min-Rimmon, Calenhad, and the Halifirien
on the borders of Rohan.”
—J. R. R. Tolkien, The Return of the King, 1955

In a scene that was brilliantly captured in Peter Jackson’s film


adaptation of The Return of the King, Rohan is alerted to the
danger to Gondor by a succession of signal fires moving from
mountain top to mountain top. This scene is a perfect illustration
of the idea of message passing in a linked list.

Minas Tirith Amon Dîn Eilenach Nardol Erelas Min-Rimmon Calenhad Halifirien Rohan
Message Passing in Linked Structures
To represent this message-passing public class SignalTower {
image, you might use a definition /* Constructs a new signal tower */
such as the one shown on the right. public SignalTower(String name,
SignalTower link) {
You can then initialize a chain of towerName = name;
nextTower = link;
SignalTower objects, like this: }
/*
Minas Tirith Min-Rimmon * Signals this tower and passes the
* message along to the next one.
*/
Amon Dîn Calenhad
public void signal() {
lightCurrentTower();
if (nextTower != null) {
nextTower.signal();
Eilenach Halifirien }
}

Nardol Rohan
/* Marks this tower as lit */
public void lightCurrentTower() {
null
. . . code to draw a fire on this tower . . .
}
Erelas
/* Private instance variables */
private String towerName;
Calling signal on the first tower private SignalTower nextTower;
}
sends a message down the chain.
public static void main(String[] args) {
SignalTower rohan = new SignalTower("Rohan", null);
SignalTower halifirien = new SignalTower("Halifirien", rohan);
SignalTower calenhad = new SignalTower("Calenhad", halifirien);
SignalTower minRimmon = new SignalTower("Min-Rimmon", calenhad);
SignalTower erelas = new SignalTower("Erelas", minRimmon);
SignalTower nardol = new SignalTower("Nardol", erelas);
SignalTower eilenach = new SignalTower("Eilenach", nardol);
SignalTower amonDin = new SignalTower("Amin Din", eilenach);
SignalTower minasTirith = new SignalTower("Minas Tirith", amonDin);

minasTirith.signal();
}

You might also like