No Slide Title

Download Report

Transcript No Slide Title

Java Memory
Management
Charles-François THUEUX
Sitraka Inc.
[email protected]
Overview
• Review of Java’s Memory Model
• Loitering Objects
• Effective Memory Management
– Design
– Implementation
– Documentation
• Conclusion and Further Reading
Stuttgart JUG 2001
2
Memory 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
Stuttgart JUG 2001
3
Memory 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
Stuttgart JUG 2001
4
Java’s 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 Heap’s
root set
Stuttgart JUG 2001
5
The 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
Stuttgart JUG 2001
6
The 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( );
Root Set:
12
myApp.method2( );
MyApp
myApp
String[] args
13
}
Stuttgart JUG 2001
7
The Dynamic Root Set - 2
14
15
16
17
18
19
20
21
22
23
24
25
26
27 }
private void
method1( )
{
BigObject bigObj = new BigObject( );
...
Root Set:
}
MyApp
myApp
String[] args
BigObject bigObj
private void
method2( )
{
BiggerObject biggerObj = new BiggerObject( );
...
}
Stuttgart JUG 2001
8
The 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( );
Root Set:
MyApp
myApp
13
}
String[] args
Stuttgart JUG 2001
9
The Dynamic Root Set - 4
14
15
16
17
18
19
20
21
22
23
24
25
26
27 }
private void
method1( )
{
BigObject bigObj = new BigObject( );
...
}
private void
method2( )
{
BiggerObject biggerObj = new BiggerObject( );
...
Root Set:
}
MyApp
myApp
String[]
args
BiggerObject biggerObj
Stuttgart JUG 2001
10
The 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
Stuttgart JUG 2001
11
Reachable Objects
• Elements within the Root
Set refer to objects within
the JVM’s Heap
Root Set
Object
• Reference variables within
those objects refer to
further objects within the
Heap
Stuttgart JUG 2001
Reference
12
Object States
• Define three progressive object “states”
– Allocated
• Exists within the JVM’s 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 application’s 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.
Stuttgart JUG 2001
13
The JVM Heap
allocated
reachable
Memory leak in
C/C++ (handled
by JVM’s GC)
“Memory leak”
in Java
live
Stuttgart JUG 2001
14
C/C++ vs. Java
• Memory leak in C/C++
– Object was allocated, but it’s not reachable
•malloc()/new, but forgot to free()/delete
before destroying the memory pointer
• “Memory leak” in Java
– The object is reachable, but it’s not live
• a reference was set, but it hasn’t been eliminated
– Object is reachable to the GC, but the source
code to fix the leak may not be available to you
Stuttgart JUG 2001
15
“Memory 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)
Stuttgart JUG 2001
Unintentional
reference
16
Loitering Objects
• The term “Memory Leak” has too much
historical baggage from C/C++
– and it doesn’t 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
Stuttgart JUG 2001
17
Reference 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
Stuttgart JUG 2001
18
Reference 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
Stuttgart JUG 2001
19
1. 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
Stuttgart JUG 2001
20
Lifecycle Relationships
• Object B adopts A’s lifecycle and has no
control over it
Stuttgart JUG 2001
21
1a. 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
Stuttgart JUG 2001
22
1a. 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
Stuttgart JUG 2001
23
1b. 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
Stuttgart JUG 2001
24
1b. 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 )
Stuttgart JUG 2001
25
2. Implementation
• Loitering objects often arise from simple
coding oversights or omissions
– forgot to null-ify a variable
– didn’t remove an object from a list
• Use a Heap Analysis Tool to validate that
your implementation adheres to your
design
Stuttgart JUG 2001
26
Reference 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
Stuttgart JUG 2001
27
Reference Variable Scope
• Don’t be concerned about assignments to
method-based reference variables within
methods of short execution time
• Be attentive of assignments to classbased and object-based reference
variables, and method-based reference
variables within methods of long
execution times
Stuttgart JUG 2001
28
Lingerer
• 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
Stuttgart JUG 2001
29
Lingerer 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 GC’ed until next print
Stuttgart JUG 2001
30
Lingerer Strategies
• Don’t 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
Stuttgart JUG 2001
31
3. 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.
Stuttgart JUG 2001
32
Dealing 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 ?
Stuttgart JUG 2001
33
Using 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 ?
Stuttgart JUG 2001
34
Notify the Author
• You’ve 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
Stuttgart JUG 2001
35
Eliminate 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
Stuttgart JUG 2001
36
Conclusion
• 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
Stuttgart JUG 2001
37
Further 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?id
=249&mon=1&yr=2001
• How Do You Plug Java Memory Leaks ? by Ethan Henry and Ed
Lycklama, Dr. Dobb’s Journal, Java Q&A 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/ftp_feat
ure.shtml
Stuttgart JUG 2001
38