Encontrar MemoryLeaks en estructuras de datos -- javascript camp codereview Relacionados El problema

Finding Memoryleaks In Data Structures


4
vote

problema

Español

Buscando críticas constructivas en mi código a continuación para detectar una fuga de memoria en una estructura de datos.

      MemoryLeak = {    uniq_id: (new Date()).getTime(),   checked: 1,   is_seen: [],    checkLeaks: function(obj) {     var self = MemoryLeak      if(!obj || (typeof obj == 'function') || self.checked > 20000)       return;      if ((self._isArray(obj) || self._isObject(obj))) {       if (self._isArray(obj)) {         self._logTooBig(obj, obj.length)         for (var i = 0; i < obj.length; i++) {           self._checkIfNeeded(obj[i])         }       }       else if (self._isObject(obj)) {         self._logTooBig(obj, self._keys(obj).length)          for (var key in obj) {           self._checkIfNeeded(obj[key])         }       }     }   };    _checkIfNeeded: function(obj) {     if (!obj)       return;      var self = MemoryLeak;     self.checked++      if ((self._isArray(obj) || self._isObject(obj))) {       if(obj.__leaks_checked == self.uniq_id)         return;       obj.__leaks_checked = self.uniq_id        setTimeout(self._partial(self.checkLeaks, obj), 5);     }   };    _logTooBig: function(obj, limit) {     if (limit > 200) {       console.log('Object too big, memory leak? [size: ' + limit + ']')       console.log(obj)       console.log('-------')     }   };    _keys: function(obj) {     var rval = [], prop     for (prop in obj)       rval.push(prop)     return rval;   };    _isArray: function(obj) {     try {       return obj instanceof Array     }     catch(e) {       return false;     }   };    _isObject: function(obj) {     return (typeof obj == 'object')   };    _partial: function(fn) {     var args = Array.prototype.slice.call(arguments)     args.shift()     return function() {       var new_args = Array.prototype.slice.call(arguments)       args = args.concat(new_args)       return fn.apply(window, args)     }   } }   
Original en ingles

Looking for constructive criticism on my code below for detecting a memory leak in a data structure.

    MemoryLeak = {    uniq_id: (new Date()).getTime(),   checked: 1,   is_seen: [],    checkLeaks: function(obj) {     var self = MemoryLeak      if(!obj || (typeof obj == 'function') || self.checked > 20000)       return;      if ((self._isArray(obj) || self._isObject(obj))) {       if (self._isArray(obj)) {         self._logTooBig(obj, obj.length)         for (var i = 0; i < obj.length; i++) {           self._checkIfNeeded(obj[i])         }       }       else if (self._isObject(obj)) {         self._logTooBig(obj, self._keys(obj).length)          for (var key in obj) {           self._checkIfNeeded(obj[key])         }       }     }   };    _checkIfNeeded: function(obj) {     if (!obj)       return;      var self = MemoryLeak;     self.checked++      if ((self._isArray(obj) || self._isObject(obj))) {       if(obj.__leaks_checked == self.uniq_id)         return;       obj.__leaks_checked = self.uniq_id        setTimeout(self._partial(self.checkLeaks, obj), 5);     }   };    _logTooBig: function(obj, limit) {     if (limit > 200) {       console.log('Object too big, memory leak? [size: ' + limit + ']')       console.log(obj)       console.log('-------')     }   };    _keys: function(obj) {     var rval = [], prop     for (prop in obj)       rval.push(prop)     return rval;   };    _isArray: function(obj) {     try {       return obj instanceof Array     }     catch(e) {       return false;     }   };    _isObject: function(obj) {     return (typeof obj == 'object')   };    _partial: function(fn) {     var args = Array.prototype.slice.call(arguments)     args.shift()     return function() {       var new_args = Array.prototype.slice.call(arguments)       args = args.concat(new_args)       return fn.apply(window, args)     }   } } 
  

Lista de respuestas

1
 
vote
vote
La mejor respuesta
 

Estoy un poco confundido aquí

  if ((self._isArray(obj) || self._isObject(obj))) {   if (self._isArray(obj)) {     self._logTooBig(obj, obj.length)     for (var i = 0; i < obj.length; i++) {       self._checkIfNeeded(obj[i])     }   }   else if (self._isObject(obj)) {     self._logTooBig(obj, self._keys(obj).length)      for (var key in obj) {       self._checkIfNeeded(obj[key])     }   } }   

Porque parece que estás haciendo las mismas dos preguntas dos veces.

¿Por qué no deshacerse de la declaración externa si simplemente lo hace

    if (self._isArray(obj)) {     self._logTooBig(obj, obj.length)     for (var i = 0; i < obj.length; i++) {       self._checkIfNeeded(obj[i])     }   }   else if (self._isObject(obj)) {     self._logTooBig(obj, self._keys(obj).length)      for (var key in obj) {       self._checkIfNeeded(obj[key])     }   }   

es exactamente lo mismo

 

I am a little confused here

if ((self._isArray(obj) || self._isObject(obj))) {   if (self._isArray(obj)) {     self._logTooBig(obj, obj.length)     for (var i = 0; i < obj.length; i++) {       self._checkIfNeeded(obj[i])     }   }   else if (self._isObject(obj)) {     self._logTooBig(obj, self._keys(obj).length)      for (var key in obj) {       self._checkIfNeeded(obj[key])     }   } } 

because it looks like you are asking the same two questions twice.

why not get rid of the outside if statement and simply make it

  if (self._isArray(obj)) {     self._logTooBig(obj, obj.length)     for (var i = 0; i < obj.length; i++) {       self._checkIfNeeded(obj[i])     }   }   else if (self._isObject(obj)) {     self._logTooBig(obj, self._keys(obj).length)      for (var key in obj) {       self._checkIfNeeded(obj[key])     }   } 

it is the exact same thing

 
 
2
 
vote
  _logTooBig: function(obj, limit) {   if (limit > 200) {     console.log('Object too big, memory leak? [size: ' + limit + ']')     console.log(obj)   

nombramiento: seguramente el parámetro que ha llamado limit debe ser nombrado size ! La palabra "límite" implica un límite superior, como en "límite de velocidad". En este caso, el "límite" en el tamaño del objeto es var operations = function() { if (operator === "+") { result = parseInt(hiddenNum) + parseInt(result); } else if (operator === "-") { result = parseInt(hiddenNum) - parseInt(result); } else if (operator === "*") { result = parseInt(hiddenNum) * parseInt(result); } else if (operator === "/") { result = parseInt(hiddenNum) / parseInt(result); } resultDisplay.innerHTML = result; }; 0 . El parámetro que actualmente ha llamado var operations = function() { if (operator === "+") { result = parseInt(hiddenNum) + parseInt(result); } else if (operator === "-") { result = parseInt(hiddenNum) - parseInt(result); } else if (operator === "*") { result = parseInt(hiddenNum) * parseInt(result); } else if (operator === "/") { result = parseInt(hiddenNum) / parseInt(result); } resultDisplay.innerHTML = result; }; 1 es lo que se supone que debe ser comparando con el límite de tamaño. Lo que realmente representa es solo un tamaño .

.

por separado, ¿está en todo lo que le preocupa que se le interese en repetidas ocasiones var operations = function() { if (operator === "+") { result = parseInt(hiddenNum) + parseInt(result); } else if (operator === "-") { result = parseInt(hiddenNum) - parseInt(result); } else if (operator === "*") { result = parseInt(hiddenNum) * parseInt(result); } else if (operator === "/") { result = parseInt(hiddenNum) / parseInt(result); } resultDisplay.innerHTML = result; }; 2 Ging (solo) Los objetos enormes serán una mala experiencia de depuración? ¿O los buenos navegadores ya manejan objetos enormes simplemente?


  var operations = function() {     if (operator === "+") {         result = parseInt(hiddenNum) + parseInt(result);     } else if (operator === "-") {         result = parseInt(hiddenNum) - parseInt(result);     } else if (operator === "*") {         result = parseInt(hiddenNum) * parseInt(result);     } else if (operator === "/") {         result = parseInt(hiddenNum) / parseInt(result);     }     resultDisplay.innerHTML = result; }; 3  

Sintaxis NIT: Falta punto y semicolón después de var operations = function() { if (operator === "+") { result = parseInt(hiddenNum) + parseInt(result); } else if (operator === "-") { result = parseInt(hiddenNum) - parseInt(result); } else if (operator === "*") { result = parseInt(hiddenNum) * parseInt(result); } else if (operator === "/") { result = parseInt(hiddenNum) / parseInt(result); } resultDisplay.innerHTML = result; }; 4 . Esto es legal, por supuesto, pero creo que muchas linturas lo marcarán como una inconsistencia.

¿Por qué haces esto con var operations = function() { if (operator === "+") { result = parseInt(hiddenNum) + parseInt(result); } else if (operator === "-") { result = parseInt(hiddenNum) - parseInt(result); } else if (operator === "*") { result = parseInt(hiddenNum) * parseInt(result); } else if (operator === "/") { result = parseInt(hiddenNum) / parseInt(result); } resultDisplay.innerHTML = result; }; 5 en lugar de decir solo var operations = function() { if (operator === "+") { result = parseInt(hiddenNum) + parseInt(result); } else if (operator === "-") { result = parseInt(hiddenNum) - parseInt(result); } else if (operator === "*") { result = parseInt(hiddenNum) * parseInt(result); } else if (operator === "/") { result = parseInt(hiddenNum) / parseInt(result); } resultDisplay.innerHTML = result; }; 6 ? Podría estar exponiendo mi propia falta de conocimiento aquí, pero pensé que var operations = function() { if (operator === "+") { result = parseInt(hiddenNum) + parseInt(result); } else if (operator === "-") { result = parseInt(hiddenNum) - parseInt(result); } else if (operator === "*") { result = parseInt(hiddenNum) * parseInt(result); } else if (operator === "/") { result = parseInt(hiddenNum) / parseInt(result); } resultDisplay.innerHTML = result; }; 7 se suponía que debía hacer lo correcto en las funciones "Miembros" llamadas con el 99887776655443318 Sintaxis. ¿Está su uso de var operations = function() { if (operator === "+") { result = parseInt(hiddenNum) + parseInt(result); } else if (operator === "-") { result = parseInt(hiddenNum) - parseInt(result); } else if (operator === "*") { result = parseInt(hiddenNum) * parseInt(result); } else if (operator === "/") { result = parseInt(hiddenNum) / parseInt(result); } resultDisplay.innerHTML = result; }; 9 en realidad trabajando alrededor de un problema con result0 , o es solo una idiosincrasia que podría limpiarse?


  result1  

Una vez más, puedo estar exponiendo mi propia falta de conocimiento, pero tengo un 75% seguro de que result2 no puede lanzar una excepción. ¿Qué caso estás preocupado por aquí?


  result3  

Esto debería ser reescrito al menos

  result4  

y (a menos que me esté perdiendo algo), simplemente debería ser

  result5  

  result6  

Veo dónde inicializa result7 y donde usted result8 , pero no veo a ninguna parte que result9 'S Value disminuye o es Reiniciar. Entonces, ¿solo revisas a las entidades de 20000 y luego dejes de registrarte para siempre? Eso no parece un comportamiento súper útil, ya que las fugas de memoria típicamente se manifiestan solo después de un tiempo bastante largo. ¿Cuál es el punto del operator0 ? (Si lo guarda, entonces sería una buena idea agregar un operator11 explicando por qué es deseable. Los comentarios del código son excelentes para explicar la "por qué" del Código).

Hablando de "Explique el por qué": habría sido agradable ver un ejemplo de cómo espera que el usuario lo use> use este verificador de fugas. Requiero que él simplemente insertaría una llamada a operator2 Después de inicializar el objeto, y eso activaría la comprobación de operator3 cada 5 segundos para las iteraciones 20000?


Ciertamente exponiendo mi ignorancia: no era consciente de que todos tus 99887766655443334 eran legales. Pensé que tendrías que hacerlos operator5 .

 
_logTooBig: function(obj, limit) {   if (limit > 200) {     console.log('Object too big, memory leak? [size: ' + limit + ']')     console.log(obj) 

Naming: Surely the parameter you've called limit ought to be named size! The word "limit" implies an upper bound, as in "speed limit". In this case, the "limit" on object size is 200. The parameter you've currently called limit is the thing you're supposed to be comparing to the size limit. What it actually represents is just a size.

Separately, are you at all worried that repeatedly console.logging (only) huge objects will be a bad debugging experience? Or do good browsers already handle huge objects just fine?


var self = MemoryLeak; self.checked++ 

Syntax nit: missing semicolon after ++. This is legal of course, but I think many linters will flag it as an inconsistency.

Why do you do this thing with self = MemoryLeak instead of just saying this.checked++? I might be exposing my own lack of knowledge here, but I thought this was supposed to do the right thing in "member" functions called with the MemoryLeak.foo() syntax. Is your use of self actually working around a problem with this, or is it just an idiosyncrasy that could be cleaned up?


try {   return obj instanceof Array } catch(e) {   return false; } 

Again I may be exposing my own lack of knowledge, but I'm about 75% sure that instanceof cannot possibly throw an exception. What case are you worried about here?


  _keys: function(obj) {     var rval = [], prop     for (prop in obj)       rval.push(prop)     return rval;   }; 

This should at least be rewritten

  _keys: function(obj) {     var rval = [];     for (var prop in obj)       rval.push(prop);     return rval;   }; 

and (unless I'm missing something) it should simply be

  _keys: function(obj) { return Object.keys(obj); } 

if(!obj || (typeof obj == 'function') || self.checked > 20000)   return; 

I see where you initialize checked = 1 and where you checked++, but I don't see anywhere that checked's value decreases or is reset. So do you only ever check 20000 entities and then stop checking forever? That doesn't seem like super useful behavior, since memory leaks typically manifest only after a fairly long time. What's the point of the checked counter? (If you keep it, then it would be a good idea to add a //code comment explaining why it's desirable. Code comments are great for explaining the "why" of code.)

Speaking of "explain the why": it would have been nice to see an example of how you expect the user to use this leak checker. I gather that he'd just insert a call to MemoryLeak.checkLeaks(mySuspiciousObject) after initializing the object, and that would trigger the checking of mySuspiciousObject every 5 seconds for 20000 iterations?


Certainly exposing my ignorance: I wasn't aware that all your };s were legal. I thought you'd have to make them },.

 
 

Relacionados problema

7  Elementos de anidación con apendchild  ( Nesting elements with appendchild ) 
Quiero hacer un navegación que se vea así: <nav class="socialmediaicons"> <ul> <li> <a> <img> </a> </li> </ul> </nav> ...

3  Página web basada en una muestra de un libro  ( Web page based on a sample from a book ) 
He creado una página web basada en una muestra de un libro. Funciona bien, pero parece haber sido demasiado complicado. dt4 ¿Es posible mejorar la clari...

5  Función de movimiento para un juego  ( Move function for a game ) 
Tengo una función PackageSubpackageSubpackageName6 en este juego que estoy haciendo. Funciona bien, pero me gustaría reducir un poco su tamaño. PackageSu...

7  Merge Sort en JavaScript  ( Merge sort in javascript ) 
Implementé este tipo de fusión en JS y noté que para los números de enteros aleatorios es mucho más rápido que la construcción en funciones de tipo de todos l...

2  Limpiando una galería de imágenes rotativas  ( Cleaning up a rotating image gallery ) 
He creado una pequeña galería de imágenes para la web. Me propuse querer 3 cosas. 1. Toda la galería tenía una capacidad de respuesta a nivel básica. 2. La ga...

1  Enviando la página web actual a un sitio de marcadores  ( Submitting the current webpage to a bookmarking site ) 
Me gustaría escuchar sus comentarios sobre el siguiente enlace que permite a los usuarios agregar un enlace a un sitio web. Leí que join()5 es sugerido en...

10  "Stardust" Simulador 2D Gravity - Seguimiento 1: Los planetas  ( Stardust 2d gravity simulator follow up 1 the planets ) 
Este es un seguimiento para el juego de gravedad del simulador 2D pregunta. Desde entonces, he desarrollado mis habilidades de JavaScript, y ahora esto...

3  Función de estilo sortable jquery  ( Jquery sortable style function ) 
Esta es una función de clasificación básica escrita en jQuery que mueve los elementos en la DOM alrededor para crear espacios vacíos para un gotpable (). Como...

3  Convertir un estado de hash a un objeto JavaScript  ( Converting a state from hash into a javascript object ) 
Este código obtiene un estado desde una parte de hash de una cadena de consulta, convierte la parte de hash a un objeto JavaScript y luego intenta obtener un ...

2  IMACROS BOT para realizar refrescos  ( Imacros bot for performing refreshes ) 
Estoy tratando de simplificar este código. Parece que todo funciona como debería; Sin embargo, cuando en el bucle de actualización de Imacro, parece un poco i...




© 2022 respuesta.top Reservados todos los derechos. Centro de preguntas y respuestas reservados todos los derechos