Skip to content

Instantly share code, notes, and snippets.

@JackieChiles
Last active June 29, 2020 19:39
Show Gist options
  • Save JackieChiles/5960c7f73dd7849064ebe43f22dbf4ed to your computer and use it in GitHub Desktop.
Save JackieChiles/5960c7f73dd7849064ebe43f22dbf4ed to your computer and use it in GitHub Desktop.
Each Memory Test
import Component from '@glimmer/component';
import { later } from '@ember/runloop';
import { tracked } from '@glimmer/tracking';
import { A } from '@ember/array';
import { action } from '@ember/object';
export default class MemoryTester extends Component {
constructor(owner, args) {
super(owner, args);
this.initialHeapSize = this.snapshotHeapSize();
this.finalHeapSize = this.initialHeapSize;
}
@tracked
initialHeapSize = 0;
@tracked
finalHeapSize = 0;
@tracked
numCycles = 100;
get heapSizeDiff() {
return this.finalHeapSize - this.initialHeapSize;
}
get heapSizeDiffMB() {
const mb = Math.round(this.heapSizeDiff / 1000000);
return `${mb} MB`;
}
get heapSizePercentChange() {
const change = (this.heapSizeDiff / (this.initialHeapSize || 1) * 100).toFixed(3);
return `${change}%`;
}
@tracked
cyclesRemaining = this.numCycles;
@tracked
rows = A();
snapshotHeapSize() {
return window.performance.memory.usedJSHeapSize;
}
getRandomizedString() {
return Math.random().toFixed(2);
}
@action
runTests(cycles) {
const period = 10;
const numRows = 50;
// Alternative example of replacing the array entirely is in the commented lines. The same memory leak results.
const rows = this.rows;
// Create a brand new array
//const rows = A();
rows.removeObjects(rows);
this.cyclesRemaining = cycles;
for (let i = 0; i < numRows; i++) {
rows.pushObject({
cycle: cycles,
index: i,
a: { value: this.getRandomizedString() },
b: { value: this.getRandomizedString() },
c: { value: this.getRandomizedString() },
d: { value: this.getRandomizedString() },
e: { value: this.getRandomizedString() }
});
}
// Update the rows property
// this.rows = rows;
if (cycles > 0) {
later(this, function () {
this.runTests(cycles - 1);
}, period);
} else {
this.finalHeapSize = this.snapshotHeapSize();
}
}
}
<table>
<thead>
<tr>
<th></th>
<th>
<h3>Heap Size</h3>
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<h3>Initial</h3>
</td>
<td class="heap-size">
{{this.initialHeapSize}}
</td>
</tr>
<tr>
<td>
<h3>Final</h3>
</td>
<td class="heap-size">
{{this.finalHeapSize}}
</td>
</tr>
<tr>
<td>
<h3>Diff</h3>
</td>
<td class="heap-size">
{{this.heapSizeDiff}}
</td>
</tr>
<tr>
<td>
<h3>MB Diff</h3>
</td>
<td class="heap-size">
{{this.heapSizeDiffMB}}
</td>
</tr>
<tr>
<td>
<h3>% Change</h3>
</td>
<td class="heap-size">
{{this.heapSizePercentChange}}
</td>
</tr>
</tbody>
</table>
<button {{on "click" (fn this.runTests this.numCycles)}}>Run Tests</button>
Cycles remaining: {{this.cyclesRemaining}}
{{#each this.rows as |row|}}
<div>
<span>{{row.a.value}}</span>
<span>{{row.b.value}}</span>
<span>{{row.c.value}}</span>
<span>{{row.d.value}}</span>
<span>{{row.e.value}}</span>
</div>
{{/each}}
<style>
td.heap-size {
font: monospace;
font-size: 24px;
text-align: right;
}
</style>
{
"version": "0.17.1",
"EmberENV": {
"FEATURES": {},
"_TEMPLATE_ONLY_GLIMMER_COMPONENTS": false,
"_APPLICATION_TEMPLATE_WRAPPER": true,
"_JQUERY_INTEGRATION": true
},
"options": {
"use_pods": true,
"enable-testing": false
},
"dependencies": {
"jquery": "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.js",
"ember": "3.18.1",
"ember-template-compiler": "3.18.1",
"ember-testing": "3.18.1"
},
"addons": {
"@glimmer/component": "1.0.0"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment