EDITAR: Réponse de Yury est meilleur.
tl;dr IMO il n'y a pas de fuite de mémoire. La pente positive est simplement l'effet de setInterval et setTimeout. Les déchets sont collectés, comme le montrent les motifs en dents de scie, ce qui signifie par définition qu'il n'y a pas de fuite de mémoire. (Je pense).
Je ne suis pas sûr qu'il y ait un moyen de contourner cette soi-disant "fuite de mémoire". Dans ce cas, la "fuite de mémoire" se réfère à chaque appel à la fonction setInterval qui augmente l'utilisation de la mémoire, comme le montrent les pentes positives dans le profileur de mémoire.
En réalité, il n'y a pas de fuite de mémoire : le ramasse-miettes est toujours en mesure de collecter la mémoire. Par définition, une fuite de mémoire "se produit lorsqu'un programme informatique acquiert de la mémoire mais ne la restitue pas au système d'exploitation".
Comme le montrent les profils de mémoire ci-dessous, il n'y a pas de fuite de mémoire. L'utilisation de la mémoire augmente à chaque appel de fonction. Le PO s'attend à ce qu'il n'y ait pas d'augmentation de la mémoire parce qu'il s'agit de la même fonction qui est appelée à plusieurs reprises. Or, ce n'est pas le cas. La mémoire est consommée à chaque appel de fonction. Finalement, les déchets sont collectés, ce qui crée le schéma en dents de scie.
J'ai exploré plusieurs façons de réorganiser les intervalles, et elles aboutissent toutes au même schéma en dents de scie (bien que certaines tentatives aient conduit à ce que le ramassage des ordures ne se produise jamais, car les références étaient conservées).
function doIt() {
console.log("hai")
}
function a() {
doIt();
setTimeout(b, 50);
}
function b() {
doIt();
setTimeout(a, 50);
}
a();
http://fiddle.jshell.net/QNRSK/14/
function b() {
var a = setInterval(function() {
console.log("Hello");
clearInterval(a);
b();
}, 50);
}
b();
http://fiddle.jshell.net/QNRSK/17/
function init()
{
var ref = window.setInterval(function() { draw(); }, 50);
}
function draw()
{
console.log('Hello');
}
init();
http://fiddle.jshell.net/QNRSK/20/
function init()
{
window.ref = window.setInterval(function() { draw(); }, 50);
}
function draw()
{
console.log('Hello');
clearInterval(window.ref);
init();
}
init();
http://fiddle.jshell.net/QNRSK/21/
Apparemment setTimeout
y setInterval
ne font pas officiellement partie de Javascript (et ne font donc pas partie de la v8). L'implémentation est laissée à l'appréciation de l'implémenteur. Je vous suggère de jeter un coup d'œil à l'implémentation de setInterval et autres dans node.js