LeakPair: Proactive Repairing of
Leaks in Single Page Web Applications
Arooba Shahoor�Department of Computer Science and Engineering
Kyungpook National University, Korea��June 5, 2024
2
MOTIVATION
3
4
What is a memory leak?
Continuous allocation of memory without releasing it when no longer used.
Continuous reduction in available memory.
The Rise of Single Page Apps (SPAs)
5
Why Are Memory Leaks Critical in the SPA Architecture?
6
Multi Page Application Architecture
7
Client
Page switching with reload
User Interface
Page 1
Page 2
Page 3
HTTP Request for initial page load
HTTP Request for page transition
Server
<template>
Presentation Layer
Database & Business Logic
New page for each request
Inside the Heap
Object 3
Object 2
Object 4
Object 1
Allocated objects from previous page all wiped off
On user interactions
Single Page Application Architecture
8
Client
�
No reload required
SPA Framework (Angular/React/Vue..)
Single .html file
<template 1>
<template 2>
<template 3>
View switching without reload
User Interface
View 1
View 2
View 3
HTTP Request for initial page load
AJAX Request for page transition
Server
Database & Business Logic
Object 3
Object 4
Object 2
Object 1
Object 6
Object 5
This page is never refreshed…
On user interactions
Inside the Heap
Unintentional references will keep piling up!
Object 7
Object 8
Object 9
JavaScript Devs Can’t Rely on Garbage Collectors
9
Garbage Collection in JS (Mark and Sweep)
Reachability from Root
10
Object 4
Object 5
Object 2
Object 8
Object 6
Object 7
Object 3
Object 1
View 1 (Inside Heap)
window
(GC ROOT 1)
String
(GC ROOT 2)
Garbage Collection in JS (Mark and Sweep)
Reachability from Root
11
Object 4
Object 5
Object 2
Object 8
UNUSED
Object 7
UNUSED
Object 1
View 2 (Inside Heap)
UNUSED
UNUSED
window
(GC ROOT 1)
String
(GC ROOT 2)
Garbage Collection in JS (Mark and Sweep)
Reachability from Root
12
UNUSED
MARK
Object 5
MARK
Object 2
MARK
UNUSED
MARK
UNUSED
MARK
Object 7
SWEEP
UNUSED
MARK
Object 1
MARK
View 2 (Inside Heap)
Unused objects marked as alive and will not be GC’ed, due to reachability from GC root
window
(GC ROOT 1)
String
(GC ROOT 2)
Garbage Collection in JS (Mark and Sweep)
Reachability from Root
13
UNUSED
MARK
Object 5
MARK
Object 2
MARK
UNUSED
MARK
UNUSED
MARK
UNUSED
MARK
Object 1
MARK
View 2 (Inside Heap)
window
(GC ROOT 1)
String
(GC ROOT 2)
Garbage Collection in JS (Mark and Sweep)
Reachability from Root
14
UNUSED
Object 5
Object 2
UNUSED
UNUSED
UNUSED
Object 1
View 3 (Inside Heap)
window
(GC ROOT 1)
String
(GC ROOT 2)
New object 1
New object 2
Lingering unwanted objects will keep gobbling up available space for newer objects
New object 3
Case in Point
15
Memory Leak in MS Rooster [2]
Reachable from root
The fix
16
Impact of Memory Leaks�(Why Not to Ignore)
17
How often?
S. H. Jensen, M. Sridharan, K. Sen, and S. Chandra, ‘MemInsight: platform-independent memory debugging for JavaScript’, in Proceedings of the 2015 10th Joint Meeting on Foundations of Software Engineering, New York, NY, USA, Aug. 2015, pp. 345–356. doi: 10.1145/2786805.2786860
18
So why no one is talking about it?
19
Leak Detection in JS
Automation Efforts (2015-2022)
2015. MemInsight➤
2016. LeakSpot
2018. BLeak
2022. Memlab➹
20
➤ S. H. Jensen, M. Sridharan, K. Sen, and S. Chandra, ‘MemInsight: platform-independent memory debugging for JavaScript’, in Proceedings of the 2015 10th Joint Meeting on Foundations of Software Engineering, New York, NY, USA, Aug. 2015, pp. 345–356. doi: 10.1145/2786805.2786860
M. Rudafshani and P. A. Ward, “LeakSpot: Detection and diagnosis of memory leaks in JavaScript Applications,” Software: Practice and Experience, vol. 47, no. 1, pp. 97–123, 2016.
J.Vilk and E. D. Berger, “BLeak: automatically debugging memory leaks in web applications,” in Proceedings of the 39th ACM SIGPLAN Conference on Programming Language Design and Implementation, New York, NY, USA, Jun. 2018, pp. 15–29. doi: 10.1145/3192366.3192376.
The Problem With Automated Detection Tools
MemInsight
LeakSpot
21
BLeak
Memlab
Based on staleness criteria + report leak-related data rather than actual leak locations
Takes at least 10 mins to execute
Reported retainer traces contain metadata and internal objects, making root cause detection arduous
Require manually-written scenario file
State of the Art
22
A change of perspective
23
What we need is…
Proactive Approach
Based on fix patterns↟.
24
↟D. Kim, J. Nam, J. Song, and S. Kim, “Automatic patch generation learned from human-written patches,” in 2013 35th International Conference on Software Engineering (ICSE). San Francisco, CA, USA: IEEE, 2013, pp. 802–811
LeakPair
25
Leak Pattern Mining
26
Fix Pattern Mining
27
5 Leaks and (Corresponding) Fix Patterns
28
1. Uncleared Timing Events (setTimeout and setInterval)
29
{
…
setTimeOut(() => {...})
…
}
{
…
- setTimeOut(() => {...})
+ timeOutID = setTimeOut(() => {...})
...
+ destructorMethodDeclaration() {
...
+ clearTimeOut(timeOutID)
+ }
}
If component unmounts before time, these events will still execute, retaining references of all enclosing objects.
Fix Pattern
Leak Pattern
2. Unremoved Event Listener
30
function listenerHandler() {
...
}
...
eventTarget
.addEventListener(eventType, listenerHandler)
{
function listenerHandler() {
...
}
...
eventTarget
.addEventListener(eventType, listenerHandler, options)
...
+ destructorMethodDeclaration() {
...
+ eventTarget.removeEventListener(eventType, listenerHandler)
+ }
}
Event listeners retain references of all enclosing variables.
Fix Pattern
Leak Pattern
3. Uncancelled Animation Frame Requests
31
{
…
requestAnimationFrame(() => {...})
…
}
…
�+ let requestID = requestAnimationFrame(() => { ...})
…
+ destructorMethodDeclaration() {
...
+ cancelAnimationFrame(requestID)
+ }
Fix Pattern
Leak Pattern
4. Unreleased Subscription
32
{
…
observer1.subscribe(() => {...})
…
}
{
…
observer1
+ .pipe(takeUntil(observer2))
.subscribe(() => {...})
…
+ destructorMethodDeclaration() {
...
+ observer2.next()
+ observer2.complete()
+ }
}
Leak Pattern
Fix Pattern
5a. Component instance event listeners (Vue only)
33
...
this.$on(event, callback);
...
...
this.$on(event, callback);
...
+ destructorMethodDeclaration() {
+ this.$off(event, callback);
+ }
Fix Pattern
Leak Pattern
5b. Root instance event listeners (Vue only)
34
...
this.root.$on(event, callback);
...
...
this.root.$on(event, callback);
...
+ destructorMethodDeclaration() {
+ this.root.$off(event, callback);
+ }
Fix Pattern
Leak Pattern
5c. Unremoved Event bus (Vue only)
35
import EventBus from ’../EventBus’;
...
EventBus.$on(event, callback);
...
import EventBus from ’../EventBus’;
...
EventBus.$on(event, callback);
...
+ destructorMethodDeclaration() {
+ EventBus.$off(event, callback);
+ }
Fix Pattern
Leak Pattern
Coverage of Selected Patterns
36
Applying Fix Patterns
37
SPA project
Identify JS file(s)
Transform to AST
Find leak pattern matches
Match found?
Apply fix to AST
Yes
Convert back to source
EVALUATION
38
Research Questions
RQ1. Effectiveness How effective is the tool at minimizing memory leaks?
RQ2. Acceptance How useful are generated patches, as perceived by developers?
RQ3. Correctness What is the impact of our tool on test suite execution results?
39
Subjects
40
Known leaks Leaks already detected and fixed by developers.
Unknown leaks Leaks developers were not aware of.
30 open source SPA projects with already known memory leaks.
30 projects with unfound leaks at the time of evaluation
41
Effectiveness Evaluation (RQ 1)
Compare before and after footprints
Execute Memlab (10 Iterations)
Note memory footprints
SPA subject
LEAKPAIR
Execute LeakPair
Run the SPA Subject
Scenario file (10 Loops)
Note memory footprints again
42
Effectiveness Evaluation (RQ 1)
Compare before and after footprints
Execute Memlab (10 Iterations)
Note memory footprints
SPA subject
LEAKPAIR
Execute LeakPair
Run the SPA Subject
Scenario file (10 Loops)
Note memory footprints again
43
Compare before and after footprints
Acceptance Evaluation (RQ 2)
Is heap size or leak count reduced?
Yes
Is unknown leak?
Yes
Submit fix as PR
Track PR status
44
Correctness Evaluation (RQ 3)
Execute test suite
(If available)
SPA subject
LEAKPAIR
Execute LeakPair
Run the SPA Subject
Note build/ compile time
Note passing/failing test cases
Note build/compile time and test case results again
Compare before and after test cases results and execution times
RESULTS
45
Effectiveness (RQ 1)
46
LeakPair’s patches can successfully prevent leaks and reduce heap, without leak detection.
Acceptance (RQ 2)
47
Merged | Approved | Improved | Ignored |
12 | 3 | 1 | 16 |
LeakPair’s patches are acceptable to developers, with half of patch suggestions being accepted.
Correctness (RQ 3)
48
The patches are non-intrusive; they neither break functionality, nor incur execution time delays.
Summary
49