Skip to content

Instantly share code, notes, and snippets.

@JackieChiles
Last active June 29, 2020 19:24
Show Gist options
  • Save JackieChiles/db56c7be1c5dd470a069395ff79efe52 to your computer and use it in GitHub Desktop.
Save JackieChiles/db56c7be1c5dd470a069395ff79efe52 to your computer and use it in GitHub Desktop.
Each Memory Test 3.12
import Component from '@ember/component';
import { later } from '@ember/runloop';
import { A } from '@ember/array';
import { computed } from '@ember/object';
const numCycles = 100;
export default Component.extend({
init() {
this._super(...arguments);
this.set('initialHeapSize', this.snapshotHeapSize())
this.set('finalHeapSize', this.get('initialHeapSize'));
this.set('rows', A());
},
initialHeapSize: 0,
finalHeapSize: 0,
heapSizeDiff: computed('finalHeapSize', 'initialHeapSize', function () {
return this.get('finalHeapSize') - this.get('initialHeapSize');
}),
heapSizeDiffMB: computed('heapSizeDiff', function () {
const mb = Math.round(this.get('heapSizeDiff') / 1000000);
return `${mb} MB`;
}),
heapSizePercentChange: computed('heapSizeDiff', 'initialHeapSize', function () {
const change = (this.get('heapSizeDiff') / (this.get('initialHeapSize') || 1) * 100).toFixed(3);
return `${change}%`;
}),
cyclesRemaining: numCycles,
snapshotHeapSize() {
return window.performance.memory.usedJSHeapSize;
},
getRandomizedString() {
return Math.random().toFixed(2);
},
runTests(cycles = numCycles) {
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.get('rows');
// Create a brand new array
//const rows = A();
rows.removeObjects(rows);
this.set('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.set('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">
{{initialHeapSize}}
</td>
</tr>
<tr>
<td>
<h3>Final</h3>
</td>
<td class="heap-size">
{{finalHeapSize}}
</td>
</tr>
<tr>
<td>
<h3>Diff</h3>
</td>
<td class="heap-size">
{{heapSizeDiff}}
</td>
</tr>
<tr>
<td>
<h3>MB Diff</h3>
</td>
<td class="heap-size">
{{heapSizeDiffMB}}
</td>
</tr>
<tr>
<td>
<h3>% Change</h3>
</td>
<td class="heap-size">
{{heapSizePercentChange}}
</td>
</tr>
</tbody>
</table>
<button {{action runTests 100}}>Run Tests</button>
Cycles remaining: {{cyclesRemaining}}
{{#each 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>
.data-table .dt-cell {
word-break: unset;
}
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.12.2",
"ember-template-compiler": "3.12.2",
"ember-testing": "3.12.2"
},
"addons": {
"@glimmer/component": "1.0.0"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment