31 votes

Les instances référencées par 'bound_this' uniquement ne sont pas récupérées

J'ai une question concernant les déchets-collecte dans google chrome (Version 20.0.1132.47, Ubuntu 11.04 64 bits).

Tout en comparant les tas de détritus et de vérification pour la mémoire des fuites, j'ai découvert certains cas, qui ne sont jamais nettoyés. Normalement, ce comportement peut être traqué à un programmeur d'erreur, mais dans ce cas je suis un peu paumé..

Jetez un oeil à la capture d'écran suivante Screenshot of heap-dump showing an instance (child) referenced only by 'bound_this'

L'instance 'enfant @610739" est référencé que par des " bound_this instances qui appartiennent à des fonctions de l'enfant-de l'instance elle-même. Donc, pour ma compréhension, l'enfant-instance doit être récupérées, comme la seule autre référence en gardant la main est l'enfant de l'instance elle-même (à travers le " bound_this fonctions).

Je suis à l'aide d'underscore.js' 'bindAll' la fonction d'utilité (trait de soulignement.js#bindAll) qui correspond à la " native_bind fonction de chrome (ECMA Script wiki sur bound_this)

Ai-je raté quelque chose d'évident ici et si oui, quelqu'un pourrait-il expliquer ce qu'est le maintien de ces instances en vie?

Mise à JOUR:
Dans le même temps, j'ai testé la même application dans chrominium (18.0.1025.168 (Développeur pour Construire 134367 Linux) Ubuntu 11.10) qui ne montre pas ces balançant les instances..

Mise à JOUR 2:
Suivant Esailijas astuce pour fournir un jsfiddle extrait de code, j'ai créé un (http://jsfiddle.net/8gSTR/1/) qui imite ce que je suis fondamentalement en train de faire. L'exécution de ce violon, malheureusement, ne montre pas les débordements, je suis en train de vivre dans mon application. Un tas de vidage prises alors que " a " -les instances sont encore référencés ressemble un peu semblable, mais en dépit de la référence à partir de la fenêtre.o tableau qui garde les instances vivant: Heap-dump taken during execution of jsfiddle mentioned above

Comme cette référence ne figure pas dans mon cas (capture d'écran 1) je ne sais pas ce qui empêche de chrome de la libération de ces instances...

Mise à JOUR 3:
Suivi loislos des conseils pour activer les propriétés cachées. Le résultat (avec l'une des branches élargi) peut être vu dans la capture d'écran suivante, mais il ne me prendra pas plus loin. Heap-dump with hidden properties enabled

3voto

developingjim Points 46

Vos soupçons que ce n'est pas une fuite de mémoire, mais quelque chose d'étrange avec le chrome est correct.

Je suis récemment tombé sur le même problème. IE11 ne sera pas afficher cette.func = _.bind(ce.func), car une fuite de mémoire tout en chrome, même après que vous appuyez sur la collecte des ordures bouton de 100 fois.

Il va le montrer, même après que vous exécutez google chrome avec la jsflag non-sens et d'exposer le sous-jacent garbage collector et appelle gc 100 fois.

Un moyen facile de prouver qu'il est en fait pas une fuite de chrome est de faire d'un problème mineur un problème majeur avec le navigateur et la force du moteur pour passer à l'action.

Sur l'instance qui a la limite de la fonction attribuée à lui attribuer une nouvelle propriété comme ceci:

cible.WhyAmILeaking = new Array(200000000).join("YOURNOT");

Les trois instantané technique avec chrome et vous verrez que la chaîne de caractères présents dans le tas pointant à environ 214mb. Faire ce que l'action constructive (la deuxième photo) de nouveau, et vous verrez le tas aller à 423mb ou rester à la 214mb. Si elle reste, vous êtes fait comme vous avez prouvé l'origine 214mb ont été recueillies. Si ce n'est pas faire de votre séjour à l'action destructrice (troisième photo) et il va revenir à 214mb aussi la preuve de l'origine a obtenu recueillies.

Si il reste simplement à 423mb vous, monsieur ou madame a une fuite.

Oh, et un autre groupe de pauvres âmes qui parcourait exactement la même situation: https://github.com/jashkenas/backbone/issues/2269#issuecomment-13610969

TL;DR; utiliser IE 11 pour la détection des fuites.

1voto

MarmiK Points 3384

J'ai appelé ce en EcmaScript, ce terme "lié " ce" avec classe,

Les méthodes de la classe ont "lié " ce", où ce dans le corps de la méthode est toujours lié à la classe de l'instance à partir de laquelle la méthode a été extrait, indépendamment de ce que ce paramètre est en fait passé à la méthode (le ce paramètre de la méthode est ignoré).

Maintenant, ici, dans votre exemple, il n'y a pas d'exemple de script donné ne peut donc pas être spécifique à la question,

Je dois dire que si ce n'est pas de fuite..

puis avec ce que jamais objet, classe le script est limitée, il n'ira pas en appel des ordures jusqu'à la classe/objet exister en tant que cette fonction est bornée avec le même objet.. il ordures collectées uniquement après l'un de ses parents(l'objet/de classe avec laquelle elle est bornée) champ d'application se termine.

Maintenant, si la circulaire de référence lorsque la tâche sera fini, il viendra à la fin,>> cela fonctionne comme concept de Récursivité(l'esprit de ce concept, pas le même que).. jusqu'à la fin commence à partir du dernier appel.. dans le sens inverse.. l'intérieur de la plupart des call(appel) sera d'abord commercialisé.. et ainsi de suite

Le code doit être buggé comme ils ne doivent pas se lier et de définir la fonction et le réutiliser à chaque fois.. mais si elles sont contraignantes puis aussi il devrait fonctionner correctement et ne doit pas couler jusqu'à ce que l'empreinte sort du navigateur limite de la mémoire de la piscine.

J'espère que cela va expliquer..

1voto

Nick Sharp Points 1218

Êtes-vous de déclencher une "forcé GC" en utilisant les outils de développement? Si c'est le cas et les objets persistent puis la recherche ci-dessus est de la valeur.

Si vous n'êtes pas le déclenchement d'une GC via les outils de développement, puis, ne pas oublier que la façon dont le moteur GC fonctionne est assez compliqué et il a le concept de générations de collecte (à l'aide de deux générations).

http://www.html5rocks.com/en/tutorials/memory/effectivemanagement/#toc-v8-gc

Il pourrait être simplement que vous n'avez pas atteint le seuil requis pour déclencher une génération de jeunes GC, ou que les objets ont été titularisés à l'ancienne Génération, mais que l'ancienne génération GC n'a jamais été déclenché.

Malheureusement, les outils de développement ne semblent pas montrer de quelle génération a été GC avais.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X