Static detection of memory leaks in a managed language such as Java is
attractive because it does not rely on any leak-triggering inputs,
allowing compile-time tools to find leaks before software is
released. A long-standing issue that prevents practical static memory
leak detection for Java is that it can be very expensive to statically
determine object liveness in large applications. We present a novel
(and the first practical) static leak detection technique that
bypasses this problem by considering a common leak pattern. In many
cases severe leaks occur in loops where, in each iteration, some
objects created by the iteration are unnecessarily referenced by
objects external to the loop. These unnecessary references are never
used in later loop iterations. Based on this insight, we shift our
focus from computing liveness, which is very difficult to achieve
precisely and efficiently for large programs, to the easier goal of
identifying objects that flow out of a loop but never flow back in.
We formalize this analysis using a type and effect system and present
its key properties. The analysis was implemented in a tool called
LeakChecker and used to detect leaks in eight real-world programs,
such as Eclipse, Derby, and log4j. LeakChecker not only identified
known leaks, but also discovered new ones whose causes were
unknown beforehand, while exhibiting a false positive rate suitable
for practical use.
LeakChecker: Practical Static Memory Leak Detection for Managed Languages
1. LeakChecker:
Prac,cal
Sta,c
Memory
Leak
Detec,on
for
Managed
Languages
Dacong
(Tony)
Yan1,
Guoqing
Xu2,
Shengqian
Yang1,
Atanas
Rountev1
1
Ohio
State
University
2
University
of
California,
Irvine
PRESTO:
Program
Analyses
and
So5ware
Tools
Research
Group,
Ohio
State
University
2. Memory
Leaks
in
Managed
Languages
• Languages
such
as
Java
sMll
have
memory
leaks:
unnecessary
references
keep
unused
objects
alive
• StaMc
leak
detecMon
– Widely
used
for
unmanaged
languages
such
as
C
– Cannot
be
applied
to
managed
languages:
no
explicit
memory
deallocaMon
• General
definiMon
of
leaks
– Precision:
difficult
to
compute
object
liveness
precisely
– Performance:
limited
scalability
for
large
programs
• Our
approach
– Shi5
the
focus,
and
idenMfy
common
leak
paVerns
2
3. Proposed
Leak
DetecMon
for
Java
• ObservaMon:
leaks
are
o5en
related
to
frequently
occurring
events
(e.g.,
loop
iteraMons)
• SoluMon:
focus
on
a
user-‐specified
event
loop
• ObservaMon:
a
leaking
object
is
o5en
– created
by
one
loop
iteraMon
– escapes
this
iteraMon
– never
used
in
later
iteraMons
• SoluMon:
interprocedural
tracking
of
3
– whether
an
object
escapes
to
a
memory
locaMon
outside
of
the
loop
– whether
an
escaping
object
flows
from
the
outside
locaMon
back
into
a
later
loop
iteraMon
4. Example
“main”:!
7 class Transaction {!
1 Transaction t = new Transaction();! 8
Order prev;!
2 for (int i = 0; i < X; ++i) {!
Customer[] custs = new Customer[…];
9
3
t.display();!
10
4
Order order = new Order(...);!
11
Order r = this.prev;!
5
t.process(order);!
12
… // display r!
13
this.prev = null; // remove!
6 }!
void display() {!
!
14
} !
21 class Customer {!
15
void process(Order p) {!
22
Order[] orders = new Order[…];!
16
this.prev = p;!
23
void addOrder(Order q) {!
17
Customer c = this.custs[…];!
18
c.addOrder(p);!
19
... // process p!
24
25
this.orders[...] = q;!
}!
26 }!
20
!
}
}!
An
example
adapted
from
SPECjbb2000
!
4
5. Example
“main”:!
7 class Transaction {!
1 Transaction t = new Transaction();! 8
Order prev;!
2 for (int i = 0; i < X; ++i) {!
Customer[] custs = new Customer[…];
9
3
t.display();!
10
4
Order order = new Order(...);!
11
Order r = this.prev;!
5
t.process(order);!
12
… // display r!
13
this.prev = null; // remove!
6 }!
void display() {!
!
14
} !
21 class Customer {!
15
void process(Order p) {!
22
Order[] orders = new Order[…];!
16
this.prev = p;!
23
void addOrder(Order q) {!
17
Customer c = this.custs[…];!
18
c.addOrder(p);!
19
... // process p!
24
25
this.orders[...] = q;!
}!
26 }!
20
!
}
}!
An
example
adapted
from
SPECjbb2000
!
5
6. Example
“main”:!
7 class Transaction {!
1 Transaction t = new Transaction();! 8
Order prev;!
2 for (int i = 0; i < X; ++i) {!
Customer[] custs = new Customer[…];
9
3
t.display();!
10
4
Order order = new Order(...);!
11
Order r = this.prev;!
5
t.process(order);!
12
… // display r!
13
this.prev = null; // remove!
6 }!
loop
object
!
void display() {!
14
} !
21 class Customer {!
15
void process(Order p) {!
22
Order[] orders = new Order[…];!
16
this.prev = p;!
23
void addOrder(Order q) {!
17
Customer c = this.custs[…];!
18
c.addOrder(p);!
19
... // process p!
24
25
this.orders[...] = q;!
}!
26 }!
!
20
!
6
}
}!
7. “main”:!
outside
object
Example
7 class Transaction {!
1 Transaction t = new Transaction();! 8
Order prev;!
2 for (int i = 0; i < X; ++i) {!
Customer[] custs = new Customer[…];
9
3
t.display();!
10
4
Order order = new Order(...);!
11
Order r = this.prev;!
5
t.process(order);!
12
… // display r!
13
this.prev = null; // remove!
6 }!
loop
object
!
void display() {!
14
} !
21 class Customer {!
15
void process(Order p) {!
22
Order[] orders = new Order[…];!
16
this.prev = p;!
23
void addOrder(Order q) {!
17
Customer c = this.custs[…];!
18
c.addOrder(p);!
19
... // process p!
24
25
this.orders[...] = q;!
}!
26 }!
!
20
!
7
}
}!
8. “main”:!
outside
object
Example
7 class Transaction {!
1 Transaction t = new Transaction();! 8
Order prev;!
2 for (int i = 0; i < X; ++i) {!
Customer[] custs = new Customer[…];
9
3
t.display();!
10
4
Order order = new Order(...);!
11
Order r = this.prev;!
5
t.process(order);!
12
… // display r!
13
this.prev = null; // remove!
6 }!
loop
object
!
void display() {!
14
} !
21 class Customer {!
15
void process(Order p) {!
22
Order[] orders = new Order[…];!
16
this.prev = p;!
23
void addOrder(Order q) {!
17
Customer c = this.custs[…];!
18
c.addOrder(p);!
19
... // process p!
24
25
this.orders[...] = q;!
}!
26 }!
!
20
!
8
}
}!
9. “main”:!
outside
object
Example
7 class Transaction {!
1 Transaction t = new Transaction();! 8
Order prev;!
2 for (int i = 0; i < X; ++i) {!
Customer[] custs = new Customer[…];
9
3
t.display();!
10
4
Order order = new Order(...);!
11
Order r = this.prev;!
5
t.process(order);!
12
… // display r!
13
this.prev = null; // remove!
6 }!
loop
object
!
void display() {!
14
} !
21 class Customer {!
15
void process(Order p) {!
22
Order[] orders = new Order[…];!
16
this.prev = p;!
23
void addOrder(Order q) {!
17
Customer c = this.custs[…];!
18
c.addOrder(p);!
19
... // process p!
24
25
this.orders[...] = q;!
}!
26 }!
!
20
!
9
}
}!
10. Example
“main”:!
7 class Transaction {!
1 Transaction t = new Transaction();! 8
Order prev;!
2 for (int i = 0; i < X; ++i) {!
Customer[] custs = new Customer[…];
9
3
t.display();!
10
4
Order order = new Order(...);!
11
Order r = this.prev;!
5
t.process(order);!
12
… // display r!
13
this.prev = null; // remove!
6 }!
void display() {!
!
14
} !
21 class Customer {!
15
void process(Order p) {!
22
Order[] orders = new Order[…];!
16
this.prev = p;!
23
void addOrder(Order q) {!
17
Customer c = this.custs[…];!
18
c.addOrder(p);!
19
... // process p!
24
25
this.orders[...] = q;!
}!
26 }!
!
20
!
10
}
}!
11. Example
“main”:!
7 class Transaction {!
1 Transaction t = new Transaction();! 8
Order prev;!
2 for (int i = 0; i < X; ++i) {!
Customer[] custs = new Customer[…];
9
3
t.display();!
10
4
Order order = new Order(...);!
11
Order r = this.prev;!
5
t.process(order);!
12
… // display r!
13
this.prev = null; // remove!
6 }!
void display() {!
!
14
} !
21 class Customer {!
15
void process(Order p) {!
22
Order[] orders = new Order[…];!
16
this.prev = p;!
23
void addOrder(Order q) {!
17
Customer c = this.custs[…];!
18
c.addOrder(p);!
19
... // process p!
24
25
this.orders[...] = q;!
}!
26 }!
!
20
!
11
}
}!
12. Example
“main”:!
7 class Transaction {!
1 Transaction t = new Transaction();! 8
Order prev;!
2 for (int i = 0; i < X; ++i) {!
Customer[] custs = new Customer[…];
9
3
t.display();!
10
4
Order order = new Order(...);!
11
Order r = this.prev;!
5
t.process(order);!
12
… // display r!
13
this.prev = null; // remove!
6 }!
void display() {!
!
14
} !
21 class Customer {!
15
void process(Order p) {!
22
Order[] orders = new Order[…];!
16
23
void addOrder(Order q) {!
17
this.prev = p;! store16
Customer c = this.custs[…];!
18
c.addOrder(p);!
19
... // process p!
24
25
this.orders[...] = q;!
}!
26 }!
!
20
!
12
}
}!
13. Example
“main”:!
7 class Transaction {!
1 Transaction t = new Transaction();! 8
Order prev;!
2 for (int i = 0; i < X; ++i) {!
Customer[] custs = new Customer[…];
9
3
t.display();!
10
4
Order order = new Order(...);!
11
Order r = this.prev;!
5
t.process(order);!
12
… // display r!
13
this.prev = null; // remove!
6 }!
void display() {!
!
14
} !
21 class Customer {!
15
void process(Order p) {!
22
Order[] orders = new Order[…];!
16
23
void addOrder(Order q) {!
17
this.prev = p;! store16
Customer c = this.custs[…];!
18
c.addOrder(p);!
19
... // process p!
24
25
this.orders[...] = q;!
}!
26 }!
Order4!
store16
20
Transaction1!
!
!
13
escape
}
}!
14. Example
“main”:!
7 class Transaction {!
1 Transaction t = new Transaction();! 8
Order prev;!
2 for (int i = 0; i < X; ++i) {!
Customer[] custs = new Customer[…];
9
3
t.display();!
10
4
Order order = new Order(...);!
11
Order r = this.prev;!
5
t.process(order);!
12
… // display r!
13
this.prev = null; // remove!
6 }!
void display() {!
!
14
} !
21 class Customer {!
15
void process(Order p) {!
22
Order[] orders = new Order[…];!
16
this.prev = p;!
23
void addOrder(Order q) {!
17
Customer c = this.custs[…];!
18
c.addOrder(p);!
19
... // process p!
this.orders[...] = q;! store24
24
25
}!
26 }!
!
20
!
14
}
}!
15. Example
“main”:!
7 class Transaction {!
1 Transaction t = new Transaction();! 8
Order prev;!
2 for (int i = 0; i < X; ++i) {!
Customer[] custs = new Customer[…];
9
3
t.display();!
10
4
Order order = new Order(...);!
11
Order r = this.prev;!
5
t.process(order);!
12
… // display r!
13
this.prev = null; // remove!
6 }!
void display() {!
!
14
} !
21 class Customer {!
15
void process(Order p) {!
22
Order[] orders = new Order[…];!
16
this.prev = p;!
23
void addOrder(Order q) {!
17
Customer c = this.custs[…];!
18
c.addOrder(p);!
19
... // process p!
this.orders[...] = q;! store24
24
25
}!
26 }!
Order4!
15
20
store24
Order[]23!
store22
!
Customer?!
!
}
store?
escape
}!
Customer[]10!
store9
Transaction1!
16. Example
“main”:!
7 class Transaction {!
1 Transaction t = new Transaction();! 8
Order prev;!
2 for (int i = 0; i < X; ++i) {!
Customer[] custs = new Customer[…];
9
3
t.display();!
10
4
Order order = new Order(...);!
11
Order r = this.prev;!
5
t.process(order);!
12
… // display r!
13
this.prev = null; // remove!
6 }!
void display() {!
!
14
} !
21 class Customer {!
15
void process(Order p) {!
22
Order[] orders = new Order[…];!
16
this.prev = p;!
23
void addOrder(Order q) {!
17
Customer c = this.custs[…];!
18
c.addOrder(p);!
19
... // process p!
24
25
this.orders[...] = q;!
}!
26 }!
!
Order4,i!
16
20
store24/orders,
…,
store9/custs
store16/prev
}
}!
Transaction1!
!
17. Example
“main”:!
7 class Transaction {!
1 Transaction t = new Transaction();! 8
Order prev;!
2 for (int i = 0; i < X; ++i) {!
Customer[] custs = new Customer[…];
9
3
t.display();!
10
4
Order order = new Order(...);!
11
Order r = this.prev;!
5
t.process(order);!
12
… // display r!
13
this.prev = null; // remove!
6 }!
void display() {!
!
14
} !
21 class Customer {!
15
void process(Order p) {!
22
Order[] orders = new Order[…];!
16
this.prev = p;!
23
void addOrder(Order q) {!
17
Customer c = this.custs[…];!
18
c.addOrder(p);!
19
... // process p!
24
25
this.orders[...] = q;!
}!
26 }!
Order4,i!
17
store24/orders,
…,
store9/custs
20
leaking?
!
}
}!
Transaction1!
!
18. Example
“main”:!
7 class Transaction {!
1 Transaction t = new Transaction();! 8
Order prev;!
2 for (int i = 0; i < X; ++i) {!
Customer[] custs = new Customer[…];
9
3
t.display();!
10
4
Order order = new Order(...);!
11
Order r = this.prev;!
5
t.process(order);!
12
… // display r!
13
this.prev = null; // remove!
6 }!
void display() {!
!
14
} !
21 class Customer {!
15
void process(Order p) {!
22
Order[] orders = new Order[…];!
16
this.prev = p;!
23
void addOrder(Order q) {!
17
Customer c = this.custs[…];!
18
c.addOrder(p);!
19
... // process p!
24
25
this.orders[...] = q;!
}!
26 }!
20
!
Order4,i!
18
store16/prev
}
}!
Transaction1!
!
leaking?
19. Example
“main”:!
7 class Transaction {!
1 Transaction t = new Transaction();! 8
Order prev;!
2 for (int i = 0; i < X; ++i) {!
Customer[] custs = new Customer[…];
9
3
t.display();!
10
4
Order order = new Order(...);!
11
Order r = this.prev;!
5
t.process(order);!
12
… // display r!
13
this.prev = null; // remove!
6 }!
void display() {!
load11
!
14
} !
21 class Customer {!
15
void process(Order p) {!
22
Order[] orders = new Order[…];!
16
this.prev = p;!
23
void addOrder(Order q) {!
17
Customer c = this.custs[…];!
18
c.addOrder(p);!
19
... // process p!
24
25
this.orders[...] = q;!
}!
26 }!
20
!
Order4,i!
19
store16/prev
}
}!
Transaction1!
!
leaking?
20. Example
“main”:!
7 class Transaction {!
1 Transaction t = new Transaction();! 8
Order prev;!
2 for (int i = 0; i < X; ++i) {!
Customer[] custs = new Customer[…];
9
3
t.display();!
10
4
Order order = new Order(...);!
11
Order r = this.prev;!
5
t.process(order);!
12
… // display r!
13
this.prev = null; // remove!
6 }!
void display() {!
load11
!
14
} !
21 class Customer {!
15
void process(Order p) {!
22
Order[] orders = new Order[…];!
16
this.prev = p;!
23
void addOrder(Order q) {!
17
Customer c = this.custs[…];!
18
c.addOrder(p);!
19
... // process p!
24
25
this.orders[...] = q;!
}!
26 }!
20
!
Order4,i!
20
store16/prev
}
}!
Transaction1!
!
leaking?
store16
21. Example
“main”:!
7 class Transaction {!
1 Transaction t = new Transaction();! 8
Order prev;!
2 for (int i = 0; i < X; ++i) {!
Customer[] custs = new Customer[…];
9
3
t.display();!
10
4
Order order = new Order(...);!
11
Order r = this.prev;!
5
t.process(order);!
12
… // display r!
13
this.prev = null; // remove!
6 }!
void display() {!
load11
!
14
} !
21 class Customer {!
15
void process(Order p) {!
22
Order[] orders = new Order[…];!
16
this.prev = p;!
23
void addOrder(Order q) {!
17
Customer c = this.custs[…];!
18
c.addOrder(p);!
19
... // process p!
24
25
this.orders[...] = q;!
}!
26 }!
load11/prev
!
Order4,i!
21
20
store16/prev
}
}!
Transaction1!
!
leaking?
store16
22. Example
“main”:!
7 class Transaction {!
1 Transaction t = new Transaction();! 8
Order prev;!
2 for (int i = 0; i < X; ++i) {!
Customer[] custs = new Customer[…];
9
3
t.display();!
10
4
Order order = new Order(...);!
11
Order r = this.prev;!
5
t.process(order);!
12
… // display r!
13
this.prev = null; // remove!
6 }!
void display() {!
load11
!
14
} !
21 class Customer {!
15
void process(Order p) {!
22
Order[] orders = new Order[…];!
16
this.prev = p;!
23
void addOrder(Order q) {!
17
Customer c = this.custs[…];!
18
c.addOrder(p);!
19
... // process p!
24
25
26 }!
this.orders[...] = q;!
}!
(i+1)-‐th
itera,on
load11/prev
!
Order4,i!
22
i-‐th
itera,on
20
store16/prev
}
}!
Transaction1!
!
leaking?
store16
23. Example
“main”:!
7 class Transaction {!
1 Transaction t = new Transaction();! 8
Order prev;!
2 for (int i = 0; i < X; ++i) {!
Customer[] custs = new Customer[…];
9
3
t.display();!
10
4
Order order = new Order(...);!
11
Order r = this.prev;!
5
t.process(order);!
12
… // display r!
13
this.prev = null; // remove!
6 }!
void display() {!
!
14
} !
21 class Customer {!
15
void process(Order p) {!
22
Order[] orders = new Order[…];!
16
this.prev = p;!
23
void addOrder(Order q) {!
17
Customer c = this.custs[…];!
18
c.addOrder(p);!
19
... // process p!
24
25
this.orders[...] = q;!
}!
26 }!
store24/orders,
…,
store9/custs
Order4,i!
23
store16/prev
20
leaking
!
}
}!
Transaction1!
!
non-‐leaking
24. StaMc
Analysis
Outline
• Object:
pair
of
allocaMon
site
and
calling
context
• Flows-‐out
path
– Loop
object
escaping
to
outside
object
– Sequence
of
store
statements
for
the
flow
• Flows-‐in
path
– Escaping
object
flows
from
outside
object
into
the
loop
– Sequence
of
load
statements
causing
the
flow
• Loop
iteraMon
constraints
– Flows-‐in
valid
only
if
the
corresponding
Flows-‐out
occurs
in
an
earlier
iteraMon
• On-‐demand
analysis
using
context-‐free
language
reachability
to
match
store/load
and
call/return
24
25. StaMc
Analysis
Outline
• Object:
pair
of
allocaMon
site
and
calling
context
• Flows-‐out
path
– Loop
object
escaping
to
outside
object
– Sequence
of
store
statements
for
the
flow
• Flows-‐in
path
– Escaping
object
flows
from
outside
object
into
the
loop
– Sequence
of
load
statements
causing
the
flow
• Loop
iteraMon
constraints
– Flows-‐in
valid
only
if
the
corresponding
Flows-‐out
occurs
in
an
earlier
iteraMon
• On-‐demand
analysis
using
context-‐free
language
reachability
to
match
store/load
and
call/return
25
26. StaMc
Analysis
Outline
• Object:
pair
of
allocaMon
site
and
calling
context
• Flows-‐out
path
– Loop
object
escaping
to
outside
object
– Sequence
of
store
statements
for
the
flow
• Flows-‐in
path
– Escaping
object
flows
from
outside
object
into
the
loop
– Sequence
of
load
statements
causing
the
flow
• Loop
iteraMon
constraints
– Flows-‐in
valid
only
if
the
corresponding
Flows-‐out
occurs
in
an
earlier
iteraMon
• On-‐demand
analysis
using
cstore
ontext-‐free
language
store
store
store
Order4!
Order[]23!
Customer?!
Customer[]10!
Transaction1!
reachability
to
match
store/load
and
call/return
24
26
22
?
9
27. StaMc
Analysis
Outline
• Object:
pair
of
allocaMon
site
and
calling
context
• Flows-‐out
path
– Loop
object
escaping
to
outside
object
– Sequence
of
store
statements
for
the
flow
• Flows-‐in
path
– Escaping
object
flows
from
outside
object
into
the
loop
– Sequence
of
load
statements
causing
the
flow
• Loop
iteraMon
constraints
– Flows-‐in
valid
only
if
the
corresponding
Flows-‐out
occurs
in
an
earlier
iteraMon
• On-‐demand
analysis
using
context-‐free
language
reachability
to
match
store/load
and
call/return
27
28. StaMc
Analysis
Outline
• Object:
pair
of
allocaMon
site
and
calling
context
• Flows-‐out
path
– Loop
object
escaping
to
outside
object
– Sequence
of
store
statements
for
the
flow
• Flows-‐in
path
– Escaping
object
flows
from
outside
object
into
the
loop
– Sequence
of
load
statements
causing
the
flow
• Loop
iteraMon
constraints
– Flows-‐in
valid
only
if
the
corresponding
Flows-‐out
occurs
in
an
earlier
iteraMon
• On-‐demand
analysis
using
context-‐free
language
Transaction1
reachability
to
match
s! tore/load
aOrderall/return
nd
c 4,i-1!
28
load11/prev
29. StaMc
Analysis
Outline
• Object:
pair
of
allocaMon
site
and
calling
context
• Flows-‐out
path
– Loop
object
escaping
to
outside
object
– Sequence
of
store
statements
for
the
flow
• Flows-‐in
path
– Escaping
object
flows
from
outside
object
into
the
loop
– Sequence
of
load
statements
causing
the
flow
• Loop
iteraMon
constraints
– Flows-‐in
valid
only
if
the
corresponding
Flows-‐out
occurs
in
an
earlier
iteraMon
• On-‐demand
analysis
using
context-‐free
language
reachability
to
match
store/load
and
call/return
29
30. StaMc
Analysis
Outline
• Object:
pair
of
allocaMon
site
and
calling
context
• Flows-‐out
path
– Loop
object
escaping
to
outside
object
– Sequence
of
store
statements
for
the
flow
• Flows-‐in
path
– Escaping
object
flows
from
outside
object
into
the
loop
– Sequence
of
load
statements
causing
the
flow
• Loop
iteraMon
constraints
– Flows-‐in
valid
only
if
the
corresponding
Flows-‐out
occurs
in
an
earlier
iteraMon
• On-‐demand
analysis
using
context-‐free
language
bject
outside
o
reachability
to
match
store/load
and
Transaction1!
call/return
30
31. StaMc
Analysis
Outline
• Object:
pair
of
allocaMon
site
and
calling
context
• Flows-‐out
path
– Loop
object
escaping
to
outside
object
– Sequence
of
store
statements
for
the
flow
• Flows-‐in
path
– Escaping
object
flows
from
outside
object
into
the
loop
– Sequence
of
load
statements
causing
the
flow
• Loop
iteraMon
constraints
– Flows-‐in
valid
only
if
the
corresponding
Flows-‐out
occurs
in
an
earlier
iteraMon
• On-‐demand
analysis
using
context-‐free
language
bject
outside
o
reachability
to
match
store/load
and
Transaction1!
call/return
Order4,i!
31
i-‐th
itera,on
32. StaMc
Analysis
Outline
• Object:
pair
of
allocaMon
site
and
calling
context
• Flows-‐out
path
– Loop
object
escaping
to
outside
object
– Sequence
of
store
statements
for
the
flow
• Flows-‐in
path
– Escaping
object
flows
from
outside
object
into
the
loop
– Sequence
of
load
statements
causing
the
flow
• Loop
iteraMon
constraints
– Flows-‐in
valid
only
if
the
corresponding
Flows-‐out
occurs
in
an
earlier
iteraMon
• On-‐demand
analysis
using
context-‐free
language
bject
outside
o
reachability
to
match
store/load
and
Transaction1!
call/return
Order4,i!
32
i-‐th
itera,on
store16/prev
33. StaMc
Analysis
Outline
• Object:
pair
of
allocaMon
site
and
calling
context
• Flows-‐out
path
– Loop
object
escaping
to
outside
object
– Sequence
of
store
statements
for
the
flow
• Flows-‐in
path
– Escaping
object
flows
from
outside
object
into
the
loop
– Sequence
of
load
statements
causing
the
flow
• Loop
iteraMon
constraints
– Flows-‐in
valid
only
if
the
corresponding
Flows-‐out
occurs
in
an
earlier
iteraMon
• On-‐demand
analysis
using
context-‐free
language
bject
(i+1)-‐th
itera,on
load /prev
outside
o
reachability
to
match
store/load
and
Transaction1!
call/return
Order4,i!
11
33
i-‐th
itera,on
store16/prev
34. StaMc
Analysis
Outline
• Object:
pair
of
allocaMon
site
and
calling
context
• Flows-‐out
path
– Loop
object
escaping
to
outside
object
– Sequence
of
store
statements
for
the
flow
• Flows-‐in
path
– Escaping
object
flows
from
outside
object
into
the
loop
– Sequence
of
load
statements
causing
the
flow
• Loop
iteraMon
constraints
– Flows-‐in
valid
only
if
the
corresponding
Flows-‐out
occurs
in
an
earlier
iteraMon
– Captured
b analysis
u recency
abstracMon
ERA)
• On-‐demand
y
extended
sing
context-‐free
l(anguage
reachability
to
match
store/load
and
call/return
34
35. StaMc
Analysis
Outline
(cont.)
• On-‐demand
analysis
– Detect
leaks
only
for
objects
allocated
in
specified
loops
– Context-‐free
language
reachability
to
match
relevant
store/
load
and
call/return
• ConservaMve
handling
of
thread
lifeMme
– Assume
the
lifeMme
of
each
thread
exceeds
the
loop
lifeMme
– Capture
objects
leaking
to
long-‐running
threads
35
36. Analysis
ImplementaMon
• Memory
leak
– An
object
leaks
if
it
starts
a
flows-‐out
path,
but
does
not
have
a
matching
flows-‐in
path
• ReporMng
leaks
– Leaking
object,
with
calling
context
of
its
allocaMon
– Outside
target
object,
with
calling
context
of
its
allocaMon
– Escape-‐causing
heap
write
(store)
statement,
with
its
calling
context
• LeakChecker:
leak
detecMon
tool
built
using
Soot
36
37. EvaluaMon
• 8
real-‐world
Java
programs
– Enterprise
trading,
so5ware
tools,
databases,
logging
– 3
programs
never
studied
by
exisMng
work
• EffecMve
for
leak
detecMon?
– LeakChecker
detected
both
known
and
new
leaks
• Suitable
for
pracMcal
use?
– Analysis
running
Mme
(all
<
35
mins)
– Reasonable
false
posiMve
rate
(avg
<
50%)
• Case
studies
37
– Performed
to
understand
quality
of
leak
report
– For
each
leak
defect,
pinpoint
root
cause
and
fix
the
problem
in
<
2
hours
38. Eclipse
Diff
• Scenario:
compare
two
large
JAR
files
– runCompare
method
in
compare
plugin!
– An
arMficial
loop
to
invoke
runCompare
mulMple
Mmes
• Loop
objects
– Editor:
display
comparison
results
– HistoryEntry:
represent
list
of
opened
editors,
and
allow
users
to
navigate
them
backward/forward
• Outside
object
– History:
managed
by
another
plugin
to
save
HistoryEntry
38
compare
plugin
!!!!
Editor!
loop
objects
history
plugin
HistoryEntry!
History!
outside
object
39. Conclusions
• LeakChecker
is
both
effecMve
and
pracMcal
• Key
insights
– Capture
common
paVerns
of
leaking
behavior
– Focus
on
user-‐specified
event
loops
– Report
leaks
with
detailed
context
informaMon
39