Java Memory Management - Java Forum Stuttgart

reelingripehalfΛογισμικό & κατασκευή λογ/κού

14 Δεκ 2013 (πριν από 3 χρόνια και 4 μέρες)

59 εμφανίσεις

Java Memory
Management

Charles
-
François THUEUX

Sitraka Inc.

cft@sitraka.com

Stuttgart JUG 2001

2

Overview


Review of Java’s Memory Model


Loitering Objects


Effective Memory Management


Design


Implementation


Documentation


Conclusion and Further Reading

Stuttgart JUG 2001

3

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

4

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

5


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

Java’s Memory Model

Stuttgart JUG 2001

6

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

7

The Dynamic Root Set
-

1


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

Consider a single thread of execution...

Stuttgart JUG 2001

8

The 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

Stuttgart JUG 2001

9

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
( );

13 }

Root Set:

MyApp


myApp

String[] args

Stuttgart JUG 2001

10

The 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

Stuttgart JUG 2001

11

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

12

Reachable Objects


Elements within the Root
Set refer to objects within
the JVM’s Heap


Reference variables within
those

objects refer to
further

objects within the
Heap

Root Set

Object

Reference

Stuttgart JUG 2001

13

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

14

allocated

reachable


live

The JVM Heap

“Memory leak”
in Java

Memory leak in
C/C++ (handled
by JVM’s GC)

Stuttgart JUG 2001

15

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

16

“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)

Unintentional

reference

Stuttgart JUG 2001

17

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

18

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

19

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

20

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

21

Lifecycle Relationships







Object B adopts A’s lifecycle and
has no
control over it

Stuttgart JUG 2001

22

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

23

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

24

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

25

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

26

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

27

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

28

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
class
-
based

and
object
-
based

reference
variables, and method
-
based reference
variables within methods of
long

execution times

Stuttgart JUG 2001

29

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

30

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

31

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

32

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

33

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

34

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

35

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

36

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

37

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

38

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