I am currently investigating memory usage patterns related to JavaScript's garbage collection in an application I am developing. I have constructed a simple benchmark to better understand GC's behavior. It includes two separate tasks (Task A and Task B) as shown below.
const button = document.getElementById('begin-test');
button.onclick = () => {
console.log('start');
const LOOPS = 40000000;
let array = [];
// Task A
for (let index = 0; index < LOOPS; index++) {
const value = [{ value: index }];
array.push(value[0].value);
}
// Task B
for (let index = 0; index < LOOPS; index++) {
array.push(index);
}
array = null;
console.log('done');
}
}
Task A and Task B are executed separately, as I alternate commenting one of them during my tests. No more Javascript is executed.
The application starts with an approximate memory usage of 3MB. Post the execution of Task A, Chrome's Memory inspection tool indicates a memory usage of 230MB. Forcing a garbage collection brings it back down to 3MB. However, after executing Task B, the memory usage is reported as 580MB(!). Forcing a garbage collection again reduces memory usage back to around 3MB. This behavior is consistent across fresh tabs for each test.
I have three questions regarding this behavior:
- Is the explicit memory allocation in Task A responsible for its lower "memory wastage"?
- Why doesn't setting
array = nullimmediately trigger garbage collection? (botharray = []andarray.length = 0yield the same results) - Could the simplicity of my test be affecting its accuracy in this specific case?
GC doesn't free resources as soon as they are dereferenced. Don't rely on assumption that