Transcript PowerPoint
From Theory to Practice 2
OOP 2006
Overview
• Performance issues:
– Preparing classes for inheritance
– Memory management and release of obsolete
object references
• The sources for this lecture:
– Effective Java ™ by Joshua Bloch
• The book contains many rules of thumb
for writing a code that is clear, correct,
robust and reuseable
• Most code samples are taken from
http://java.sun.com/docs/books/effective/
– About garbage collection:
http://java.sun.com/developer/technicalArticles/ALT/RefObj/
Preparing Classes For Inheritance
• Design and document for inheritance or else
prohibit it.
What does it mean?
• Document precisely the effect of overriding
any method
• Choose protected methods judiciously
• Constructors and clone must not involve
overridable methods
• Special measures should be taken when
implementing Serializable objects
remove
Documentation
public boolean remove(Object o)
Removes a single instance of the specified element from this
collection, if it is present (optional operation). More formally, removes an
element e such that (o==null ? e==null : o.equals(e)), if the
collection contains one or more such elements. Returns true if the
collection contained the specified element (or equivalently, if the collection
changed as a result of the call).This implementation iterates over the
collection looking for the specified element. If it finds the element, it
removes the element from the collection using the iterator's remove
method.
Note that this implementation throws an UnsupportedOperationException
if the iterator returned by this collection's iterator method does not
implement the remove method and this collection contains the specified
object.
A description of the effect of overriding a method in
AbstractCollection
Choosing Protected Methods
• Consider the API of abstractList
List subList(int fromIndex, int toIndex)
Returns a view of the portion of this list between fromIndex,
inclusive, and toIndex, exclusive.
void clear()
Removes all of the elements from this collection (optional
operation).
• The following method is called by clear
protected void removeRange(int fromIndex, int toIndex)
Removes from this list all of the elements whose index is between
fromIndex, inclusive, and toIndex, exclusive.
• Allows efficient implementation of clear in
inherited class
Constructors
• What happens if the constructor invokes
overridable method?
public class Super {
// Broken - constructor invokes overridable method
public Super() {
m();
}
public void m() {
}
}
Constructors
final class Sub extends Super {
// Blank final, set by constructor
private final Date date;
Sub() {
date = new Date();
}
// Overrides Super.m, invoked by the constructor Super()
public void m() {
System.out.println(date);
}
public static void main(String[] args) {
Sub s = new Sub(); The program prints null
s.m();
}
}
Memory Management in Java
• The memory in java is handled in two main
structures:
– Program execution stack: contains the memory
required by method invocation
– The memory heap: contains the memory required
by objects in the program
• The new command allocates memory for an
object and activates its constructor
Releasing Unused Objects
• Memory release of unreferenced objects is
handled using garbage collection
• The garbage collector:
– Identify objects that are no-longer in use
– Recycle memory occupied by such objects
• An object is in use if it can be accessed or
reached by the program in its current state
• In order to define a reachable object we first
define the root set of references
The Root Set and Reachable
Objects
• The root set of references includes:
– References to objects in active methods of the
program:
• Method arguments
• Local variables
– Static reference variables
– References reiterated through the Java Native
Interface (JNI)
• An object is reachable if
– It is referenced by a reference from the root set
– It is referenced by another reachable object
The Root Set and Reachable
Objects
Java Heap
Unreachable objects (garbage)
Root set
of references
Reachable objects
Advantage of Garbage collected
Heap
• In programming languages such as C and
C++, the programmer manages memory
allocation and release
• In Java, the programmer does not have to
deal with memory allocation
• But special care should be taken to avoid
memory leaks – where not-used objects still
occupy memory
Example – Stack Implementation
public class Stack {
private Object[] elements;
private int size = 0;
public Stack(int initialCapacity) {
this.elements = new Object[initialCapacity];
}
public void push(Object e) {
ensureCapacity();
elements[size++] = e;
}
private void ensureCapacity() {
if (elements.length == size) {
Object[] oldElements = elements;
elements = new Object[2 * elements.length + 1];
System.arraycopy(oldElements, 0, elements, 0, size);
}
Stack Implementation - continue
// Can you spot the memory leak?
public Object pop() {
if (size==0)
throw new EmptyStackException();
Object result = elements[--size];
return result;
}
• If the stack shrinks, objects that were popped of
the stack will not be garbage collected
• Memory leak potential consequences
– Reduced performance due to paging or increased
garbage collection activity
– OutOfMemoryError
Solution
public Object pop() {
if (size==0)
throw new EmptyStackException();
Object result = elements[--size];
// Eliminate obsolete reference
elements[size] = null;
return result;
}
Correct Memory handling
• Memory leaks are hard to detect and
resolved (there are specialized tools for that)
• Null out object references in classes that
manage their own memory
• Special care should also be taken for caches
• Do not null out every object finishing its role:
– References of local variables fall out of scope
– Variable reuse releases the previous referenced
objects
• Define each variable in the narrowest
possible score (There are other good reasons
to do it, what are they?)