Title: Java Memory Management
1Java Memory Management
- Charles-François THUEUX
- Sitraka Inc.
- cft_at_sitraka.com
2Overview
- Review of Javas Memory Model
- Loitering Objects
- Effective Memory Management
- Design
- Implementation
- Documentation
- Conclusion and Further Reading
3Memory Safety in Java
- A key aspect in the design of...
- the Java Language
- no pointer arithmetic
- the Java Virtual Machine (JVM)
- bytecode instruction set
- runtime checks (array bounds, ref casts)
- garbage collection
4Memory Safety in Java
- Eliminated many memory-related problems
- Buffer overruns
- De-referencing stale pointers
- Memory leaks
- However Java programs can exhibit the macro-level
symptoms of traditional memory leaks - Process size seemingly grows without bounds
5Javas Memory Model
- The intent of Garbage Collection is to remove
objects that are no longer needed - Undecidable in general
- Java uses an approximation
- remove objects that are no longer reachable
- The reachability test starts at the Heaps root
set
6The Root Set
- Set of foundational object references
- static reference fields within class definitions
- local reference variables within the method
frames of each Java thread stack - The contents of the Root Set change dynamically
as your program runs - As threads enter and exit methods, local
reference variables enter and leave the Root Set
7The Dynamic Root Set - 1
Consider a single thread of execution...
- 1 public
- 2 class MyApp
- 3
- 4 private static MyApp myApp null
- 5
- 6 public static
- 7 void
- 8 main( String args )
- 9
- 10 myApp new MyApp( )
- 11 myApp.method1( )
- 12 myApp.method2( )
- 13
Root Set MyApp myApp String args
8The Dynamic Root Set - 2
- 14 private void
- 15 method1( )
- 16
- 17 BigObject bigObj new BigObject( )
- 18 ...
- 19
- 20
- 21 private void
- 22 method2( )
- 23
- 24 BiggerObject biggerObj new BiggerObject(
) - 25 ...
- 26
- 27
Root Set MyApp myApp String
args BigObject bigObj
9The Dynamic Root Set - 3
- 1 public
- 2 class MyApp
- 3
- 4 private static MyApp myApp null
- 5
- 6 public static
- 7 void
- 8 main( String args )
- 9
- 10 myApp new MyApp( )
- 11 myApp.method1( )
- 12 myApp.method2( )
- 13
Root Set MyApp myApp String args
10The Dynamic Root Set - 4
- 14 private void
- 15 method1( )
- 16
- 17 BigObject bigObj new BigObject( )
- 18 ...
- 19
- 20
- 21 private void
- 22 method2( )
- 23
- 24 BiggerObject biggerObj new BiggerObject(
) - 25 ...
- 26
- 27
Root Set MyApp myApp String
args BiggerObject biggerObj
11The Dynamic Root Set - 5
- 1 public
- 2 class MyApp
- 3
- 4 private static MyApp myApp null
- 5
- 6 public static
- 7 void
- 8 main( String args )
- 9
- 10 myApp new MyApp( )
- 11 myApp.method1( )
- 12 myApp.method2( )
- 13
Root Set MyApp myApp
12Reachable Objects
- Elements within the Root Set refer to objects
within the JVMs Heap - Reference variables within those objects refer to
further objects within the Heap
Root Set
Object
Reference
13Object States
- Define three progressive object states
- Allocated
- Exists within the JVMs heap
- Reachable
- A path exists (directly or indirectly) from a
member of the root set, through a sequence of
references, to that object. - Live
- From the intent of the applications design, the
program will use the object (meaning at least one
of its fields will be accessed and/or one of its
methods will be invoked) along some future path
of execution.
14The JVM Heap
allocated
reachable
live
15C/C vs. Java
- Memory leak in C/C
- Object was allocated, but its not reachable
- malloc()/new, but forgot to free()/delete before
destroying the memory pointer - Memory leak in Java
- The object is reachable, but its not live
- a reference was set, but it hasnt been
eliminated - Object is reachable to the GC, but the source
code to fix the leak may not be available to you
16Memory Leaks in Java
- Impact is often more severe than C/C
- Rarely a single object, but a whole sub-graph
- A single lingering reference can have massive
memory impact (and a significant performance
impact)
Unintentional reference
17Loitering Objects
- The term Memory Leak has too much historical
baggage from C/C - and it doesnt accurately describe the
formulation of the problem as it pertains to Java - A new term Loitering Object
- An object that remains within the Heap past its
useful life
18Reference Management
- The key to effective memory management in Java is
effective reference management - What undermines effective reference management ?
- Awareness of the issue
- Bad habits from C/C development
- Class Libraries and Application Frameworks
- Ill-defined reference management policies
- Encapsulate flawed reference assignments
19Reference Management
- As a Java programmer, how can I effectively
manage references within my software, and promote
better reference management ? - 1. Design
- 2. Implementation
- 3. Documentation
201. Design for Ref. Mgmt.
- For each Use Case within your application,
explicitly characterize - a. The lifecycle of each object
- b. The inter-relationships between various
objects
21Lifecycle Relationships
- Object B adopts As lifecycle and has no control
over it
A
B
221a. Object Lifecycles
- For each object within the Use Case you are
implementing, you need to explicitly define - its point of creation
- the duration of its usefulness
- the point at which it should be eliminated from
the runtime environment
231a. Object Lifecycles
- In Java, creating an object within the runtime
environment is an explicit act, while its
elimination is an implicit one - Defining - within your design - the point when
your object should be eliminated will help you
validate the correctness of your Java
implementation
241b. Inter-Object Relationships
- Objects establish relationships as they
collaborate to accomplish their goals - Examples
- Composition (a has-a relationship)
- Association (a uses-a relationship)
- Relationship lifecycles
251b. Inter-Object Relationships
- Think Symmetry
- If you define a method that establishes a
relationship, ensure you define a method that
revokes it. - The Observer Pattern
- subject.addObserver( Observer )
- subject.removeObserver( Observer )
262. Implementation
- Loitering objects often arise from simple coding
oversights or omissions - forgot to null-ify a variable
- didnt remove an object from a list
- Use a Heap Analysis Tool to validate that your
implementation adheres to your design
27Reference Variable Scope
- Three forms of reference variables
- Class-based
- Reference variables within a class definition
that have a static attribute associated with them - Object-based
- Non static reference variables within a class
definition - Method-based
- Reference variables defined within the scope of a
method
28Reference Variable Scope
- Dont be concerned about assignments to
method-based reference variables within methods
of short execution time - Be attentive of assignments to class-based and
object-based reference variables, and
method-based reference variables within methods
of long execution times
29Lingerer
- Reference used transiently by long-term object
- Reference always reset on next use
- e.g. associations with menu items
- e.g. global action or service
30Lingerer Example
- Print action as singleton
- class Printer
- has data member Printable target
- calls target.doPrint()
- target inside printer not set to null on
completion - target is a lingering reference
- target cannot be GCed until next print
31Lingerer Strategies
- Dont use a set of fields to maintain state
- enclose in object
- easier to maintain
- one reference to clean up
- Draw state diagram
- quiescent state no outgoing references
- Early exit methods or multi-stage process
- setup process cleanup
323. Documentation
- For methods that establish a relationship to
another object, identify (in your javadoc
description) the symmetric method that revokes
the relationship -
void addObserver( Observer ) Adds the Observer
argument to the subject's internal set of
observers. To remove the observer from this
internal set, invoke the removeObserver( Observer
) method.
33Dealing with Flaws of Others
- After determining you have a loitering object,
your investigation reveals that the object
holding the reference to your loiterer is one
which you do not have the source code to. - How do you handle this ?
34Using Their Code Properly ?
- Are you using their framework properly ?
- Understand their notion of object life cycles
- Think symmetry (again)
- An add() operation implies a remove()
- A register() implies an unregister()
- Does the symmetric operation (to the one that
established the reference) remove it ?
35Notify the Author
- Youve established that they are erroneously
holding an object reference - Create a simple test case
- Make it easy for the vendor to clearly identify
the issue. - Ask for
- Work arounds (if possible)
- Resolution to the fundamental problem
36Eliminate Subgraph Elements
- If you can not fix the root cause, free up as
much of the loitering subgraph as you can.
Unintentional reference
Unintentional reference
37Conclusion
- The key to effective memory management in Java is
effective reference management - Incorporate reference management in your design
- Validate your Java implementation
- Document your reference management policies so
others will know what to do
38Further Reading
- Loitering Objects and Java Framework Design by
Leonard Slipp, JavaReport, Volume 6, Number 1
(January 2001) - http//www.javareport.com/html/from_pages/article.
asp?id249mon1yr2001 - How Do You Plug Java Memory Leaks ? by Ethan
Henry and Ed Lycklama, Dr. Dobbs Journal, Java
QA Column,Volume 25, Number 2 (February 2000) - www.ddj.com/articles/2000/0002/0002l/0002l.htm
- Memory Leaks in Java Programs by Joel Nylund,
JavaReport, Volume 4, Number 11 (November 1999). - www.javareport.com/archive/9911/html/from_pages/ft
p_feature.shtml