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

07 ObjectsAndMemory

This document provides a 3 paragraph summary of a chapter on objects and memory in Java: The chapter discusses how Java allocates and manages memory for primitive types and objects. It explains that objects are stored in an area of memory called the heap, while method calls use a region called the stack to store local variables. Diagrams are used to illustrate how objects are linked together in memory using references, and how memory is reclaimed through garbage collection once objects are no longer reachable. The document provides an example of tracing object creation and method calls using a heap-stack diagram to model memory usage in Java.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
38 views

07 ObjectsAndMemory

This document provides a 3 paragraph summary of a chapter on objects and memory in Java: The chapter discusses how Java allocates and manages memory for primitive types and objects. It explains that objects are stored in an area of memory called the heap, while method calls use a region called the stack to store local variables. Diagrams are used to illustrate how objects are linked together in memory using references, and how memory is reclaimed through garbage collection once objects are no longer reachable. The document provides an example of tracing object creation and method calls using a heap-stack diagram to model memory usage in Java.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
You are on page 1/ 24

Jav

The Art and Science of

CHAPTER 7

ERIC S. ROBERTS

Objects and Memory


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

7.1
7.2
7.3
7.4

The structure of memory


The allocation of memory to variables
Primitive types vs. objects
Linking objects together

An Introduction
to Computer Science

The Structure of Memory


The fundamental unit of memory inside a computer is called a
bit, which is a contraction of the words binary digit. A bit can
be in either of two states, usually denoted as 0 and 1.

The hardware structure of a computer combines individual


bits into larger units. In most modern architectures, the
smallest unit on which the hardware operates is a sequence of
eight consecutive bits called a byte. The following diagram
shows a byte containing a combination of 0s and 1s:
0

Numbers are stored in still larger units that consist of multiple


bytes. The unit that represents the most common integer size
on a particular hardware is called a word. Because machines
have different architectures, the number of bytes in a word
may vary from machine to machine.

Binary Notation
Bytes and words can be used to represent integers of different
sizes by interpreting the bits as a number in binary notation.
Binary notation is similar to decimal notation but uses a
different base. Decimal numbers use 10 as their base, which
means that each digit counts for ten times as much as the digit
to its right. Binary notation uses base 2, which means that
each position counts for twice as much, as follows:
0

The next
Thedigit
next
The
gives
digit
rightmost
gives digit
And so on . . .
the number
the number
ofis4s.
theofunits
2s. place.

0
1
0
1
0
1
0
0

x
x
x
x
x
x
x
x

1
2
4
8
16
32
64
128

=
=
=
=
=
=
=
=

0
2
0
8
0
32
0
0
42

Numbers and Bases


The calculation at the end of the preceding slide makes it
clear that the binary representation 00101010 is equivalent to
the number 42. When it is important to distinguish the base,
the text uses a small subscript, like this:
001010102 = 4210
Although it is useful to be able to convert a number from one
base to another, it is important to remember that the number
remains the same. What changes is how you write it down.
The number 42 is what you get if you count
how many stars are in the pattern at the right.
The number is the same whether you write it
in English as forty-two, in decimal as 42, or
in binary as 00101010.
Numbers do not have bases; representations do.

Octal and Hexadecimal Notation


Because binary notation tends to get rather long, computer
scientists often prefer octal (base 8) or hexadecimal (base
16) notation instead. Octal notation uses eight digits: 0 to 7.
Hexadecimal notation uses sixteen digits: 0 to 9, followed by
the letters A through F to indicate the values 10 to 15.
The following diagrams show how the number forty-two
appears in both octal and hexadecimal notation:
octal

hexadecimal

2
2
5

x
x

1 = 2
8 = 40
42

10
02

x
x

1 = 10
16 = 32
42

The advantage of using either octal or hexadecimal notation is that


doing so makes it easy to translate the number back to individual bits
because you can convert each digit separately.

Exercises: Number Bases


What is the decimal value for each of the following numbers?

100012
1

170

1778

AD16

7 7
127

A
173D

1 x 1 = 1
7 x 1 = 7
13 x 1 = 13
0 x 2 = 0
7 x 8 = 56
10 x 16 = 160
As part of a code to identify
the
file
type,
every
Java
class file
0 x 4 = 0
1 x 64 = 64
173
begins with the following
sixteen
bits:
0 x 8 = 0
127
x
1 16 = 1
1 1 0 0 1 0 1 017 1 1 1 1 1 1 1 0

How would you express that number in hexadecimal


notation?
1

F
CAFE16

Memory and Addresses


Every byte inside the primary memory of a machine
is identified by a numeric address. The addresses
begin at 0 and extend up to the number of bytes in
the machine, as shown in the diagram on the right.
In these slides as well as in the diagrams in the text,
memory addresses appear as four-digit hexadecimal
numbers, which makes addresses easy to recognize.
In Java, it is impossible to determine the address of
an object. Memory addresses used in the examples
are therefore chosen completely arbitrarily.
Memory diagrams that show individual bytes are not
as useful as those that are organized into words. The
revised diagram on the right now includes four bytes
in each of the memory cells, which means that the
address numbers increase by four each time.

.
.
.

.
.
.

0000
0001
0004
0002
0008
0003
000C
0004
0010
0005
0014
0006
0018
0007
001C
0008
0020
0009
0024
000A
0028
000B
002C

FFD0
FFF4
FFF5
FFD4
FFF6
FFD8
FFF7
FFDC
FFF8
FFE0
FFE4
FFF9
FFFA
FFE8
FFFB
FFEC
FFFC
FFF0
FFFD
FFF4
FFFE
FFF8
FFFC
FFFF

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
are never created or destroyed as the program runs,
such as named constants and other class variables.
This information is called static data.
Whenever you create a new object, Java allocates 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.
In classical architectures, the stack and heap grow
toward each other to maximize the available space.

0000

static
data

heap

stack
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
den

1004

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 void run() {
Rational a = new Rational(1, 2);
public Rational add(Rational r) {
36
5
Rational b = new Rational(1, 3);
2
1
3
1
Rational c = new Rational(1, 6);
return new Rational( this.num * r.den + r.num * this.den ,
Rational sum = a.add(b).add(c);
this.den * r.den );
println(a + " + " + b + " + " + c + " = " + sum);
}}
36
6
heap

stack

TestRational

1000
1000

num
den

1004
1004

1008
1008

num
den

1010
1010

1014
1014

num
den

101C
101C

1020
1020

num
den

1028
1028

102C
102C

num
den

100C
100C

1018
1018

1/2 + 1/3 + 1/6 = 1

All objects are created


in the heap.
This object is a temporary value
FFE0
100C
used only during
calculation.
r the
1018
this

1000
1024

FFE8

1024
1024

1030
1030
1

1034
1034

1038
1038

FFE4

sum
c
b
a

1030

FFEC

1018

FFF0

100C
1000

FFF4
FFF8
FFFC

This stack frame is created


for the add method.
This stack frame is created
for the run method.

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
den

1004

1008

num
den

1010

1014

num
den

101C

1020

num
den

1028

102C

num
den

1034

1038

100C

1018

1024

1030

sum
c
b
a

1030

FFEC

1018

FFF0

100C
1000

FFF4
FFF8
FFFC

num
den

num
den

num
den

num
den

num
den

sum
c
b
a

Addresses vs. Pointers


The two heap-stack diagram formatsthe 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
den

1004

1008

num
den

1010

1014

num
den

101C

1020

num
den

1028

102C

num
den

1034

1038

100C

1018

1024

1030

sum
c
b
a

1030

FFEC

1018

FFF0

100C
1000

FFF4
FFF8
FFFC

num
den

num
den

num
den

num
den

num
den

sum
c
b
a

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

This object was used to hold a temporary


result and is no longer accessible.

num
den

num
den

num
den

num
den

num
den

stack

sum
c
b
a

Exercise: Stack-Heap Diagrams


Suppose that the classes Point and Line are defined as follows:
public class Point {
public Point(int x, int y) {
cx = x;
cy = y;
}
. . . other methods appear here . . .

public class Line {


public Line(Point p1,
Point p2) {
start = p1;
finish = p2;
}
. . . 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 run method returns.
public void run() {
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
stack

heap

heap

stack

1000

cx
cy

1004

1008

cx
cy

200

1010

200

1014

start
finish

1000

101C

100C

1020

cx
cy

cx
cy

200

100C

line
p2
p1

1018

1018

FFF0

100C
1000

FFF8

200

line
p2
p1

FFF4
FFFC

start
finish

Primitive Types vs. Objects


At first glance, Javas 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 objectusually by calling settershave 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.

Wrapper Classes
The designers of Java chose to separate the primitive types
from the standard class hierarchy mostly for efficiency.
Primitive values take less space and allow Java to use more of
the capabilities provided by the hardware.
Even so, there are times in which the fact that primitive types are not
objects gets in the way. There are many tools in the Java libraries
several of which you will encounter later in the bookthat work only
with objects.
To get around this problem, Java includes a wrapper class to correspond to
each of the primitive types:

boolean
byte
char
double

Boolean
Byte
Character
Double

float
int
long
short

Float
Integer
Long
Short

Using Wrapper Classes


You can create an instance of a wrapper class by calling its
constructor with the primitive value. For example, the line
Integer five = new Integer(5);

creates a new Integer object containing the value 5:


heap

stack
1000

1004

five

1000

FFFC

To value stored in the variable five is a real object, and you


can use it in any contexts that require objects.
For each of the wrapper classes, Java defines a method to
retrieve the primitive value, as illustrated below:
int underlyingValue = five.intValue();

Boxing and Unboxing


As of Java Standard Edition 5.0, Java automatically converts
values back and forth between a primitive type and the
corresponding wrapper class. For example, if you write
Integer five = 5;

Java will automatically call the Integer constructor.


Similarly, if you then write
int six = five + 1;

Java will automatically call intValue before the addition.


These operations are called boxing and unboxing.
Although boxing and unboxing can be quite convenient, this
feature can generate confusion and should be used with care.

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 (which you will encounter again in
Chapter 13) is called a linked list, in which each object in a
sequence contains a reference to the one that follows it:
data
link

data
link

data
link

data
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 Dn, 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 Jacksons 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 Dn

Eilenach

Nardol

Erelas

Min-Rimmon

Calenhad

Halifirien

Rohan

Message Passing in Linked Structures


To represent this message-passing
image, you might use a definition
such as the one shown on the right.
You can then initialize a chain of
SignalTower objects, like this:
Minas Tirith

Min-Rimmon

Amon Dn

Calenhad

Eilenach

Halifirien

Nardol

Rohan

null
Erelas

Calling signal on the first tower


the chain.
sends a message down

public class SignalTower {


/* Constructs a new signal tower */
public SignalTower(String name,
SignalTower link) {
towerName = name;
nextTower = link;
}
/*
* Signals this tower and passes the
* message along to the next one.
*/
public void signal() {
lightCurrentTower();
if (nextTower != null) {
nextTower.signal();
}
}
/* Marks this tower as lit */
public void lightCurrentTower() {
. . . code to draw a fire on this tower . . .
}
/* Private instance variables */
private String towerName;
private SignalTower nextTower;
}

TheEnd

You might also like