YOU ARE DOWNLOADING DOCUMENT

Please tick the box to continue:

Transcript
Page 1: Heap liveness  and its usage in  automatic memory management

Heap liveness and its usage in

automatic memory management

Ran Shaham

Elliot Kolodner

Mooly Sagiv

•ISMM’02

•Unpublished

http://www.cs.tau.ac.il/~ransh/

TV

LA inside

Page 2: Heap liveness  and its usage in  automatic memory management

Motivation• An object could be collected once it is no longer

needed– Yet, run-time garbage collectors (RTGCs) are

typically based on reachability• Profiling tools can detect when objects are

needed• The compiler can:

– Statically identify a subset of unneeded objects – Issue a free instruction (compile-time Garbage

Collection)– Issue a warning when a potentially needed object is

reclaimed– Inform run-time garbage collector that a reference to

an object is not further used

Page 3: Heap liveness  and its usage in  automatic memory management

A Pathological C Program

a = malloc(…) ;

b = a;

free (a);

c = malloc (…);

if (b == c) printf(“unexpected equality”);

Page 4: Heap liveness  and its usage in  automatic memory management

Inefficient Java Classpublic Class Stack { private Object stack[]; private int top; public Stack(int len) { stack = new Object[len]; top = 0; } public synchronized Object pop() { top= top-1; return stack[top]; } public synchronized void push(Object o) { stack[top]=o; top= top+1; } public synchronized void print() { for (int i=0; i<top; i++) { System.out.println(stack[i]); } }}

GC does not reclaim the memory stack[top+1]

Page 5: Heap liveness  and its usage in  automatic memory management

Needed Location

pp’

l is neededa reference to l is used

l is allocated

Page 6: Heap liveness  and its usage in  automatic memory management

Needed Reference Expression

pp’

e is needed a reference to l is used

e references l

e is not needed free(e) is valid

l is allocated

Page 7: Heap liveness  and its usage in  automatic memory management

A Pathological C Program

a = malloc(…) ;

b = a;

free (a);

c = malloc (…);

if (b == c) printf(“unexpected equality”);

a is needed

Page 8: Heap liveness  and its usage in  automatic memory management

Location Liveness

pp’

l is live

l is not assigned

l is used

Page 9: Heap liveness  and its usage in  automatic memory management

Reference Expression Liveness

pp’

e is live

e denotes a location l

l is not assigned

l is used

Generalizes liveness of program variables when l is &x

Page 10: Heap liveness  and its usage in  automatic memory management

Inefficient Java Classpublic Class Stack { private Object stack[]; private int top; public Stack(int len) { stack = new Object[len]; top = 0; } public synchronized Object pop() { top= top-1; return stack[top]; } public synchronized void push(Object o) { stack[top]=o; top= top+1; } public synchronized void print() { for (int i=0; i<top; i++) { System.out.println(stack[i]); } }}

stack[top+1] is not live

Page 11: Heap liveness  and its usage in  automatic memory management

Typical GC Limits

class Node { Node left, right; int data;}

class C { void main(…) { Node root = createTree(); processTree(root.right); }}

root

Page 12: Heap liveness  and its usage in  automatic memory management

Typical GC Limits

class Node { Node left, right; int data;}

class C { void main(…) { Node root = createTree(); processTree(root.right); }}

root

Page 13: Heap liveness  and its usage in  automatic memory management

Typical GC Limits

class Node { Node left, right; int data;}

class C { void main(…) { Node root = createTree(); processTree(root.right); }}

root

Page 14: Heap liveness  and its usage in  automatic memory management

Liveness Analysis Aids GC

class Node { Node left, right; int data;}

class C { void main(…) { Node root = createTree(); processTree(root.right); }}

root

root.right is live, root.left is dead

Page 15: Heap liveness  and its usage in  automatic memory management

Liveness Analysis Aids GC

class Node { Node left, right; int data;}

class C { void main(…) { Node root = createTree(); processTree(root.right); }}

root

root.right is live, root.left is dead

Page 16: Heap liveness  and its usage in  automatic memory management

Liveness Analysis Aids GC

class Node { Node left, right; int data;}

class C { void main(…) { Node root = createTree(); processTree(root.right); }}

root

root.right is live, root.left is dead

Page 17: Heap liveness  and its usage in  automatic memory management

Liveness Analysis Aids GC

class Node { Node left, right; int data;}

class C { void main(…) { Node root = createTree(); processTree(root.right); }}

root

root.right is live, root.left is dead

Page 18: Heap liveness  and its usage in  automatic memory management

Typical GC Limits

Program

Variables

a

b

c

d

e

f

Page 19: Heap liveness  and its usage in  automatic memory management

Outline

• Dynamic liveness measurements– Complete location liveness– Assign-null interface

• Static analysis algorithms– (Exact) assign null (improve GC)– (Exact) free (CTGC)

Page 20: Heap liveness  and its usage in  automatic memory management

Dynamic Liveness Measurements

• Estimating the potential of static analysis– Find upper bounds on expected savings

• Can be used in as an assistant tool

• Liveness information kinds– Stack reference liveness– Global reference liveness– Heap reference liveness

Page 21: Heap liveness  and its usage in  automatic memory management

Main Results

• Dynamic measurements for 10 benchmarks

• Shallow information Small Potential– local variables 2%– global variables 5%– local + global 9%

• Deep information Larger Potential– heap liveness 39% complete location liveness

15% assign-null interface

Page 22: Heap liveness  and its usage in  automatic memory management

Dynamic measurements

– Implemented via an instrumented JVM

• Complete location liveness measurements– Single-run algorithm

• Assign-null liveness interface – Determines the liveness of expressions– Assign null to dead reference expressions– Requires two runs of the program

Page 23: Heap liveness  and its usage in  automatic memory management

Complete Liveness Measurements

• An Observation

The last use of the references to an object determines the time an object could be collected assuming liveness information

Page 24: Heap liveness  and its usage in  automatic memory management

Heap Liveness Example IStack

y

z

gStatic

x

f

f2

f 1

f

fHeapL= t

use z.f

f

HeapL

= t

Page 25: Heap liveness  and its usage in  automatic memory management

Heap Liveness Example IStack

y

z

gStatic

x

f

f2

f 1

f

fHeapL= t+2

use y.f2

f

HeapL= t

= t+2

Page 26: Heap liveness  and its usage in  automatic memory management

Heap Liveness Example IIStack

y

z

gStatic

x

f

f2

f 1

f

f

StackR = t’’

f

StackR = Directly stack reachable

(computed during GC)

Collection time = max(t’, t’’)

Collection time(obj) = max(HeapL(obj), StackR(obj), StaticR(obj), OtherR(obj))

= t’’

HeapL= t’

Page 27: Heap liveness  and its usage in  automatic memory management

Complete Liveness Summary

• Mutator– Tracks the last use of references to an object

• Collector– Propagation needed for stack/static liveness– Propagates reachability information– Propagates path liveness

• Object Collection/Program Termination– Maximum of liveness/reachability properties of an object– Depends on liveness scheme (heap liveness etc.)

Page 28: Heap liveness  and its usage in  automatic memory management

Experimental Results

• Instrumented Sun’s classic JVM (1.2)

• 10 benchmarks (5 SPECjvm)

• Time is measured bytes allocated by the mutator so far in program

• Total space savings (integral)

• Maximum heap size savings (footprint)

Page 29: Heap liveness  and its usage in  automatic memory management

Analyzer - Complete Liv eness

0

0.5

1

1.5

2

2.5

3

3.5

0 50 100 150 200 250 300

allocation time (MB)

siz

e (

MB

) heap liveness

stack+staticliveness

w /out liveness

Page 30: Heap liveness  and its usage in  automatic memory management

Potential Savings – Total Space

0

0.1

0.2

0.3

0.4

0.5

0.6

0.7

0.8

jess

raytr

ace

db

javac

jack

analy

zer

juru

eule

r

mc

tvla

average

heap+stack+static liveness heap liveness

stack+static liveness static liveness

stack liveness

Page 31: Heap liveness  and its usage in  automatic memory management

Restricted GC Interface

• GC Interface– Should be simple/effective/efficient – Feasible heap liveness representation

• Assign null to dead heap references– Simple– Effective?

• Partially answered by our experiments

– Efficient?• Will be answered by static analysis

Page 32: Heap liveness  and its usage in  automatic memory management

Null Assignable Program Points

• Normalized statements (Java Bytecode)– Manipulate at most one heap reference

• x = y.f is null assignable– Could be followed by y.f = null

• Dynamic algorithm – First run

• Determine null assignable program points– Assume all program points are null assignable– Detect non-null-assignable program points during the run

– Second run• Assign null in null assignable program points

Page 33: Heap liveness  and its usage in  automatic memory management

Doubly-Linked List Example – First Run

x

n

pd d

n

pd d

// processing list elements in pairspt1: y = x.n; // x.n = null; x = null; while (y != null) { pt2: t = y.p; // y.p = null;pt3: d1 = t.d; // t.d = nullpt4: d2 = y.d; // y.d = null process(d1, d2); pt5: t = y.n; // y.n = null; y = t; }

Page 34: Heap liveness  and its usage in  automatic memory management

Doubly-Linked List Example – First Run

x

n

pd d

n

pd d

[pt1]

// processing list elements in pairspt1: y = x.n; // x.n = null; x = null; while (y != null) { pt2: t = y.p; // y.p = null;pt3: d1 = t.d; // t.d = nullpt4: d2 = y.d; // y.d = null process(d1, d2); pt5: t = y.n; // y.n = null; y = t; }

y

Page 35: Heap liveness  and its usage in  automatic memory management

Doubly-Linked List Example – First Run

n

pd d

n

pd d

yt

[pt2]

[pt1]

// processing list elements in pairspt1: y = x.n; // x.n = null; x = null; while (y != null) { pt2: t = y.p; // y.p = null;pt3: d1 = t.d; // t.d = nullpt4: d2 = y.d; // y.d = null process(d1, d2); pt5: t = y.n; // y.n = null; y = t; }

Page 36: Heap liveness  and its usage in  automatic memory management

Doubly-Linked List Example – First Run

n

pd d

n

pd d

yt

[pt2]

[pt3]

d1

[pt1]

// processing list elements in pairspt1: y = x.n; // x.n = null; x = null; while (y != null) { pt2: t = y.p; // y.p = null;pt3: d1 = t.d; // t.d = nullpt4: d2 = y.d; // y.d = null process(d1, d2); pt5: t = y.n; // y.n = null; y = t; }

Page 37: Heap liveness  and its usage in  automatic memory management

Doubly-Linked List Example – First Run

n

pd d

n

pd d

yt

[pt2]

[pt3]

d1

[pt4]

d2

[pt1]

// processing list elements in pairspt1: y = x.n; // x.n = null; x = null; while (y != null) { pt2: t = y.p; // y.p = null;pt3: d1 = t.d; // t.d = nullpt4: d2 = y.d; // y.d = null process(d1, d2); pt5: t = y.n; // y.n = null; y = t; }

Page 38: Heap liveness  and its usage in  automatic memory management

Doubly-Linked List Example – First Run

n

pd d

n

pd d

y t

[pt2]

[pt3]

d1

[pt4]

d2

[pt5][pt1]

// processing list elements in pairspt1: y = x.n; // x.n = null; x = null; while (y != null) { pt2: t = y.p; // y.p = null;pt3: d1 = t.d; // t.d = nullpt4: d2 = y.d; // y.d = null process(d1, d2); pt5: t = y.n; // y.n = null; y = t; }

Page 39: Heap liveness  and its usage in  automatic memory management

Doubly-Linked List Example – First Run

n

pd d

n

pd d

t y

[pt2]

[pt3]

d1

[pt4]

d2

[pt5]

[pt2]

[pt1]

// processing list elements in pairspt1: y = x.n; // x.n = null; x = null; while (y != null) { pt2: t = y.p; // y.p = null;pt3: d1 = t.d; // t.d = nullpt4: d2 = y.d; // y.d = null process(d1, d2); pt5: t = y.n; // y.n = null; y = t; }

Page 40: Heap liveness  and its usage in  automatic memory management

[pt4]

Doubly-Linked List Example – First Run

n

pd d

n

pd d

t y

[pt2]

[pt3]

d1

[pt3]

d2

[pt5]

[pt1]

[pt1]

// processing list elements in pairspt1: y = x.n; // x.n = null; x = null; while (y != null) { pt2: t = y.p; // y.p = null;pt3: d1 = t.d; // t.d = nullpt4: d2 = y.d; // y.d = null process(d1, d2); pt5: t = y.n; // y.n = null; y = t; }

Page 41: Heap liveness  and its usage in  automatic memory management

Doubly-Linked List Example – First Run

n

pd d

n

pd d

[pt2]

[pt3]

d2

[pt3]

d1

[pt5]

[pt3]

[pt1]

[pt3]

// processing list elements in pairspt1: y = x.n; // x.n = null; x = null; while (y != null) { pt2: t = y.p; // y.p = null;pt3: d1 = t.d; // t.d = nullpt4: d2 = y.d; process(d1, d2); pt5: t = y.n; // y.n = null; y = t; }

Page 42: Heap liveness  and its usage in  automatic memory management

Doubly-Linked List Example - Second Run

x

n

pd d

n

pd d

// processing list elements in pairspt1: y = x.n; x.n = null; x = null; while (y != null) { pt2: t = y.p; y.p = null;pt3: d1 = t.d; t.d = nullpt4: d2 = y.d; process(d1, d2); pt5: t = y.n; y.n = null; y = t; }

Page 43: Heap liveness  and its usage in  automatic memory management

n

pd d

n

pd d

ty

// processing list elements in pairspt1: y = x.n; x.n = null; x = null; while (y != null) { pt2: t = y.p; y.p = null;pt3: d1 = t.d; t.d = nullpt4: d2 = y.d; process(d1, d2); pt5: t = y.n; y.n = null; y = t; }

Doubly-Linked List Example - Second Run

d1 d2

Page 44: Heap liveness  and its usage in  automatic memory management

// processing list elements in pairspt1: y = x.n; x.n = null; x = null; while (y != null) { pt2: t = y.p; y.p = null;pt3: d1 = t.d; t.d = nullpt4: d2 = y.d; process(d1, d2); pt5: t = y.n; y.n = null; y = t; }

Doubly-Linked List Example - Second Run

d

n

pd d

ty

d1 d2

Page 45: Heap liveness  and its usage in  automatic memory management

Assign Null - Potential Savings

0%

5%

10%

15%

20%

25%

30%

35%

40%

jes

s

ray

tra

ce

db

jav

ac

jac

k

an

aly

ze

r

juru

eu

ler

mc

tvla

av

era

ge

context=0

context=1

context=2

context=3

• 15% average savings for context = 2– 11% assigning null to instance fields– 10% assigning null to array elements

• Results are valid across runs – Detecting null assignable program points on a second input– Running the program with the first input

– null assignable program points are those detected for both inputs

Page 46: Heap liveness  and its usage in  automatic memory management

Related Work

• On the Usefulness of Liveness for Garbage Collection and Leak Detection [HDH01]– Does not handle heap liveness – Algorithm requires two runs

• First run: record uses and defs• Analyze log backwards for liveness information• Second run: use liveness results

• Garbage Collection and Local Variable Type-Precision and Liveness in Java Virtual Machines [ADM98]– Stack liveness static analysis– Actual trends match our upper bounds

• On the Effectiveness of GC in Java [SKS00]– Drag information

• Slightly larger potential than heap liveness information• Not clear how to automate space savings

• HUP tool (PLDI’01 + M. Pan)

Page 47: Heap liveness  and its usage in  automatic memory management

Dynamic liveness measurements -Conclusion

• Liveness Information has large potential• Assign null savings “achievable” by static analysis• Stack liveness information

– Small potential• Stack+static liveness information

– Medium potential• Heap liveness information

– Is feasible• Recording history on heap is a powerful mechanism

– Larger potential• Depends on static analysis precision• Depends on GC interface

Page 48: Heap liveness  and its usage in  automatic memory management

Static Analysis

• Combine history with shape analysis – a-La- Horwitz, Pfeiffer, and Reps 1989

• Assign null – Assign null to a dead reference expression– GC exploits information

• Free– free an unneeded object

Page 49: Heap liveness  and its usage in  automatic memory management

Assign Null Analysis

– Insert “x.fld = null” after statements in which the expression x.fld becomes dead

– Limitations• Only one reference is assigned null• All the paths to the statement must agree

– Detects last-use– Technically

• llastu[pt,x.fld](v)– The last use of the location denoted by x.fld occurs at pt

• null[pt,x.fld]() – It is safe to insert “x.fld = null” after pt

Page 50: Heap liveness  and its usage in  automatic memory management

Assign Null Example // traversing list elements pt1: y = x; pt2: while (y != null) { pt3: t = y.n; pt4: y = t; }

x

nn

null[pt3,y.n]

Page 51: Heap liveness  and its usage in  automatic memory management

Assign Null Example // traversing list elements pt1: y = x; pt2: while (y != null) { pt3: t = y.n; pt4: y = t; }

x,y

nn

null[pt3,y.n]

Page 52: Heap liveness  and its usage in  automatic memory management

Assign Null Example // traversing list elements pt1: y = x; pt2: while (y != null) { pt3: t = y.n; pt4: y = t; }

x,y

nn

null[pt3,y.n]

Page 53: Heap liveness  and its usage in  automatic memory management

Assign Null Example // traversing list elements pt1: y = x; pt2: while (y != null) { pt3: t = y.n; pt4: y = t; }

x,y

n

llastu[pt3,y.n]

nn

t

null[pt3,y.n]

Page 54: Heap liveness  and its usage in  automatic memory management

Assign Null Example // traversing list elements pt1: y = x; pt2: while (y != null) { pt3: t = y.n; pt4: y = t; }

x

n

llastu[pt3,y.n]

nn

y,t

null[pt3,y.n]

Page 55: Heap liveness  and its usage in  automatic memory management

Assign Null Example // traversing list elements pt1: y = x; pt2: while (y != null) { pt3: t = y.n; pt4: y = t; }

x

n

llastu[pt3,y.n]

nn

y,t

null[pt3,y.n]

Page 56: Heap liveness  and its usage in  automatic memory management

Assign Null Example // traversing list elements pt1: y = x; pt2: while (y != null) { pt3: t = y.n; pt4: y = t; }

x

n

llastu[pt3,y.n]

nn

y

llastu[pt3,y.n]

nt null[pt3,y.n]

Page 57: Heap liveness  and its usage in  automatic memory management

Assign Null Example // traversing list elements pt1: y = x; pt2: while (y != null) { pt3: t = y.n; pt4: y = t; }

x

n

llastu[pt3,y.n]

nn

llastu[pt3,y.n]

n

y,t null[pt3,y.n]

Page 58: Heap liveness  and its usage in  automatic memory management

Assign Null Example // traversing list elements pt1: y = x; pt2: while (y != null) { pt3: t = y.n; pt4: y = t; }

x

n

llastu[pt3,y.n]

nn

llastu[pt3,y.n]

n

y,t null[pt3,y.n]

Page 59: Heap liveness  and its usage in  automatic memory management

Assign Null Example // traversing list elements pt1: y = x; pt2: while (y != null) { pt3: t = y.n; pt4: y = t; }

x

n

llastu[pt3,y.n]

nn

llastu[pt3,y.n]

n

llastu[pt3,y.n]

y

n

t

null[pt3,y.n]

Page 60: Heap liveness  and its usage in  automatic memory management

Assign Null Example // traversing list elements pt1: y = x; pt2: while (y != null) { pt3: t = y.n; pt4: y = t; }

x

nn

llastu[pt3,y.n]

n

llastu[pt3,y.n]

n

y,tn

null[pt3,y.n]

Page 61: Heap liveness  and its usage in  automatic memory management

Assign Null Example // traversing list elements pt1: y = x; pt2: while (y != null) { pt3: t = y.n; pt4: y = t; }

x

nn

llastu[pt3,y.n]

n

llastu[pt3,y.n]

n

y,tn

Page 62: Heap liveness  and its usage in  automatic memory management

Assign Null Example // traversing list elements pt1: y = x; pt2: while (y != null) { pt3: t = y.n; pt4: y = t; }

x

n

llastu[pt3,y.n]

nn

llastu[pt3,y.n]

n

llastu[pt3,y.n]

y

n

tn

null[pt3,y.n]

Page 63: Heap liveness  and its usage in  automatic memory management

Assign Null Example // traversing list elements pt1: y = x; pt2: while (y != null) { pt3: t = y.n; pt4: y = t; }

x

n

llastu[pt3,y.n]

nn

llastu[pt3,y.n]

n

y,tn

null[pt3,y.n]

Page 64: Heap liveness  and its usage in  automatic memory management

Assign Null Example // traversing list elements pt1: y = x; pt2: while (y != null) { pt3: t = y.n; pt4: y = t; }

x

n

llastu[pt3,y.n]

nn

llastu[pt3,y.n]

n

y,tn

null[pt3,y.n]

Page 65: Heap liveness  and its usage in  automatic memory management

Assign Null Example // traversing list elements pt1: y = x; pt2: while (y != null) { pt3: t = y.n; pt4: y = t; }

x

n

llastu[pt3,y.n]

n

llastu[pt3,y.n]

yn

llastu[pt3,y.n]

null[pt3,y.n]

Page 66: Heap liveness  and its usage in  automatic memory management

Assign Null Example // traversing list elements pt1: y = x; pt2: while (y != null) { pt3: t = y.n; pt4: y = t; }

x

n

llastu[pt3,y.n] llastu[pt3,y.n]

n

null[pt3,y.n]

Page 67: Heap liveness  and its usage in  automatic memory management

Assign Null Example // traversing list elements pt1: y = x; pt2: while (y != null) { pt3: t = y.n; pt4: y = t; }

x

n

llastu[pt3,y.n] llastu[pt3,y.n]

n

null[pt3,y.n]

Page 68: Heap liveness  and its usage in  automatic memory management

• Static Reachability Information +Static Liveness Information CT garbage detection

• Issue “free(e)” for unneeded e

Compile-Time Garbage Collection

Page 69: Heap liveness  and its usage in  automatic memory management

Exact Free Analysis

– Insert free(x) at program points when the x becomes unneeded

• Only one location is freed• All the paths to the statement must agree on the

garbage

– History predicates• lastu[pt,x](v)

– the last use of the location pointed-to by x occurs

• unneeded [pt,x]() – “free(x)” is safe after pt

Page 70: Heap liveness  and its usage in  automatic memory management

Exact Free Example // traversing list elements pt1: y = x; pt2: while (y != null) { pt3: t = y.n; pt4: y = t; }

x

nn

unneeded[pt1,x]

unneeded[pt2,y]

unneeded[pt3,y]

unneeded[pt4,t]

Page 71: Heap liveness  and its usage in  automatic memory management

Exact unneeded Example // traversing list elements pt1: y = x; pt2: while (y != null) { pt3: t = y.n; pt4: y = t; }

x,y

nn

unneeded[pt1,x]

unneeded[pt2,y]

unneeded[pt3,y]

unneeded[pt4,t]

lastu[pt1,x]

Page 72: Heap liveness  and its usage in  automatic memory management

Exact Free Example // traversing list elements pt1: y = x; pt2: while (y != null) { pt3: t = y.n; pt4: y = t; }

x,y

nn

unneeded[pt2,y]

unneeded[pt3,y]

unneeded[pt4,t]

lastu[pt2,y]

Page 73: Heap liveness  and its usage in  automatic memory management

Exact Free Example // traversing list elements pt1: y = x; pt2: while (y != null) { pt3: t = y.n; pt4: y = t; }

x

n

unneeded[pt3,y]

lastu[pt3,y] lastu[pt3,y]

n

Page 74: Heap liveness  and its usage in  automatic memory management

Preliminary Conclusions

• Heap Liveness is useful

• Can be dynamically computed for large programs

• More data is needed to confirm scalability of static analysis

• Recording local history is a powerful tool– Refines the abstraction


Related Documents