Cómo Escapar De Las Fugas De Memoria En JavaScript

Si su aplicación de JavaScript experimenta fallas frecuentes, alta latencia y bajo rendimiento, una posible causa podría ser la pérdida de memoria. Los desarrolladores a menudo descuidan la gestión de la memoria debido a conceptos erróneos sobre la asignación automática de memoria por parte de los motores de JavaScript, lo que provoca fugas de memoria y un rendimiento deficiente.

En este artículo, exploraremos la administración de memoria, los tipos de fugas de memoria y la búsqueda de fugas de memoria en JavaScript usando Chrome DevTools. ¡Empecemos!

¿Qué son las fugas de memoria?

En palabras simples, una fuga de memoria es una porción de memoria asignada que el motor de JavaScript no puede recuperar. El motor de JavaScript asigna memoria cuando crea objetos y variables en su aplicación, y es lo suficientemente inteligente como para borrar la memoria cuando ya no necesita los objetos. Las fugas de memoria se deben a fallas en su lógica y dan lugar a un rendimiento deficiente en su aplicación.

Antes de saltar a los diferentes tipos de fugas de memoria, tengamos una idea clara de la gestión de memoria en JavaScript, la recolección de elementos no utilizados .

Ciclo de vida de la memoria

En cualquier lenguaje de programación, el ciclo de vida de la memoria consta de tres pasos:

Asignación de memoria

El sistema operativo asigna memoria al programa durante la ejecución según sea necesario.

Usar memoria

Su programa usa memoria previamente asignada. Su programa puede realizar ready writeacciones en la memoria.

Liberar memoria

Una vez que finaliza su tarea, la memoria asignada se libera y queda libre. En lenguajes de alto nivel como JavaScript, el recolector de basura maneja la liberación de memoria. Si comprende cómo ocurre la asignación y liberación de memoria en JavaScript, es muy fácil resolver las fugas de memoria en su aplicación.

Asignación de memoria

JavaScript tiene dos opciones de almacenamiento para la asignación de memoria. Uno es la pila y el otro es el montón. Todos los tipos primitivos, como number, Booleano undefinedse almacenarán en la pila. Heap es el lugar para tipos de referencia como objetos, matrices y funciones.

Pila

Stack sigue el enfoque FIFO para asignar memoria. Todos los tipos primitivos como number, Booleany undefinedse pueden almacenar en la pila:

 

Montón

Los tipos de referencia como objetos, matrices y funciones se almacenan en el montón. El tamaño de los tipos de referencia no se puede determinar en el momento de la compilación, por lo que la memoria se asigna en función del uso de los objetos. La referencia del objeto se almacena en la pila y el objeto real se almacena en el montón:

En la imagen de arriba, la otherStudentvariable se crea copiando la variable del estudiante. En este escenario, otherStudentse crea en la pila, pero apunta a la referencia del estudiante en el montón.

Hemos visto que el principal desafío para la asignación de memoria en el ciclo de memoria es cuándo liberar la memoria asignada y hacerla disponible para otros recursos. En este escenario, la recolección de basura viene al rescate.

Recolector de basura

La causa principal de las fugas de memoria en una aplicación se debe a las referencias no deseadas. El recolector de elementos no utilizados encuentra la memoria que el programa ya no utiliza y la vuelve a liberar al sistema operativo para su asignación adicional.

Para saber qué es una referencia no deseada, primero, debemos tener una idea de cómo la recolección de basura determina que una parte de la memoria es inalcanzable. La recolección de basura utiliza dos algoritmos principales para encontrar referencias no deseadas y código inalcanzable, recuento de referencias y marcado y barrido.

Recuento de referencia

El algoritmo de recuento de referencias busca objetos que no tienen referencias. Un objeto puede liberarse si no tiene referencias que lo apunten.

Entendamos esto mejor con el siguiente ejemplo. Hay tres variables, student, otherStudent, que es una copia de estudiante, y sports, que toma la matriz de deportes del studentobjeto:

let student = {
    name: 'Joe',
    age: 15,
    sports: ['soccer', 'chess']
}
let otherStudent = student;
const sports = student.sports;
student = null;
otherStudent = null;

En el fragmento de código anterior, asignamos studenty otherStudentvariables a valores nulos, lo que nos dice que estos objetos no tienen referencias a ellos. La memoria que se les asigna en el montón, que está en rojo, se puede liberar fácilmente ya que no tiene referencias.

Por otro lado, tenemos otro bloque de memoria en el montón, que no se puede liberar porque tiene la sportsreferencia al objeto.

Cuando dos objetos se refieren a sí mismos, hay un problema con el algoritmo de recuento de referencias. En términos simples, si hay referencias cíclicas, este algoritmo falla en determinar objetos libres.

En el siguiente ejemplo, personse asignó a employeey employeea person, por lo que estos objetos se refieren entre sí:

let person = {
    name: 'Joe'
};
let employee = {
    id: 123
};
person.employee = employee;
employee.person = person;
person = null;
employee = null;

Después de crear estos objetos null, perderán la referencia en la pila, pero los objetos permanecerán en el montón ya que tienen la referencia cíclica. El algoritmo de referencia no pudo liberar estos objetos ya que tienen una referencia. El problema de referencia cíclica se puede resolver usando el algoritmo de marcar y barrer.

algoritmo de marcar y barrer

El algoritmo de marcar y barrer reduce la definición de un objeto innecesario a un objeto inalcanzable. Si el objeto no es accesible, el algoritmo considera que este objeto es innecesario:

El algoritmo de marcar y barrer sigue dos pasos. Primero, en JavaScript, la raíz es el objeto global. El recolector de elementos no utilizados comienza periódicamente desde la raíz y encuentra todos los objetos a los que se hace referencia desde la raíz. Marcará todos los objetos alcanzables active. Luego, la recolección de basura libera la memoria para todos los objetos que no están marcados como active, devolviendo la memoria al sistema operativo.

Tipos de fugas de memoria

Podemos evitar las fugas de memoria si comprendemos cómo se crean las referencias no deseadas en JavaScript. Los siguientes escenarios provocan referencias no deseadas.

Variables globales accidentales o no declaradas

Una de las formas en que JavaScript es permisivo es en la forma en que maneja las variables no declaradas. Una referencia a una variable no declarada crea una nueva variable dentro del objeto global. Si crea una variable sin ninguna referencia, su raíz sería el objeto global.

Como acabamos de ver en el algoritmo de marcar y barrer, las referencias que apuntan directamente a la raíz siempre son active, y el recolector de basura no puede borrarlas, lo que genera una pérdida de memoria:

function foo(){
    this.message = 'I am accidental variable';
}
foo();

Como solución, intente anular estas variables después de su uso, o agregue use strictpara habilitar un modo más estricto de JavaScript que evite las variables globales accidentales.

Cierres

Un cierre es una combinación de una función agrupada o encerrada con referencias a su estado circundante, el entorno léxico. En términos simples, un cierre es una función interna que tiene acceso al alcance de la función externa.

Las variables del ámbito de la función se limpian después de que la función haya salido de la pila de llamadas, mientras que un cierre mantiene las variables del ámbito externo a las que se hace referencia después de su ejecución. Las variables de alcance externo residen en la memoria aunque no se utilicen, por lo que esta es una causa común de fugas de memoria:

function outer(){
    const largeArray = []; // unused array
    return function inner(num){
        largeArray.push(num);
    }
}
const appendNumbers = outer(); // get the inner function
// call the inner function repeatedly
for (let i=0; i< 100000000; i++){
    appendNumbers(i);
}

En el ejemplo anterior, largeArraynunca se devuelve y el recolector de basura no puede acceder a él, lo que aumenta significativamente su tamaño a través de llamadas repetidas de funciones internas, lo que resulta en una pérdida de memoria.

Los cierres son inevitables, así que asegúrese de que las variables en el ámbito externo se usen o se devuelvan.

Temporizadores olvidados

setTimeouty setIntervalson los dos eventos de temporización disponibles en JavaScript. La setTimeoutfunción se ejecuta cuando transcurre el tiempo dado, mientras que setIntervalse ejecuta repetidamente durante el intervalo de tiempo dado. Estos temporizadores son la causa más común de pérdidas de memoria.

Si configuramos el temporizador recurrente en nuestro código, la referencia al objeto de la devolución de llamada del temporizador permanece activa hasta que el temporizador se detiene:

function generateRandomNumbers(){
    const numbers = []; // huge increasing array
    return function(){
        numbers.push(Math.random());
    }
}
setInterval((generateRandomNumbers(), 2000));

En el ejemplo anterior, generateRandomNumbersdevuelve una función que agrega números aleatorios a la matriz de números de alcance externo. Al usar setIntervalesta función, llama al intervalo especificado periódicamente y da como resultado un tamaño enorme para la matriz de números.

Para resolver este problema, las mejores prácticas requieren proporcionar referencias dentro de las llamadas setTimeoutor . setIntervalLuego, haga una llamada explícita para borrar los temporizadores. Para el ejemplo anterior, la solución es la siguiente:

const timer = setInterval(generateRandomNumbers(), 2000); // save the timer
    // on any event like button click or mouse over etc
    clearInterval(timer); // stop the timer

Fuera de referencia DOM

Fuera de la referencia DOM indica nodos que se han eliminado del DOM pero que aún están disponibles en la memoria. El recolector de elementos no utilizados no puede liberar estos objetos DOM, ya que se denominan memoria gráfica de objetos. Entendamos esto con un ejemplo a continuación:

let parent = document.getElementById("#parent");
let child = document.getElementById("#child");
parent.addEventListener("click", function(){
    child.remove(); // removed from the DOM but not from the object memory
});

En el código anterior, eliminamos el elemento secundario del DOM al hacer clic en el principal, pero la variable secundaria aún contiene la memoria porque el detector de eventos siempre es active, y contiene la referencia secundaria. Por este motivo, el recolector de elementos no utilizados no puede liberar el objeto secundario y seguirá consumiendo la memoria.

Siempre debe anular el registro de los detectores de eventos una vez que ya no los necesite creando la referencia para el detector de eventos y pasándola al removeEventListenermétodo:

function removeChild(){
    child.remove();
}
parent.addEventListener("click", removeChild);
// after completing required action
parent.removeEventListener("click", removeChild);

Identifique fugas de memoria con Chrome DevTools

La depuración de problemas de memoria es realmente un trabajo difícil, pero podemos identificar el gráfico de memoria y algunas fugas de memoria con Chrome DevTools. Nos centraremos en dos aspectos importantes de nuestra vida diaria como desarrolladores:

  1. Visualice el consumo de memoria con el generador de perfiles de rendimiento
  2. Identifique los nodos DOM separados.

Visualice el consumo de memoria con el generador de perfiles de rendimiento

Consideremos el siguiente fragmento de código como ejemplo. Hay dos botones, Print Numbersy Clear. Con un clic en el botón Imprimir números , los números desde 1hasta 10,000se agregan al DOM creando nodos de párrafo y empujando algunas cadenas enormes a la variable global.

El botón Borrar borrará la variable global y anulará el cuerpo del documento, pero no eliminará los nodos creados al hacer clic en Imprimir :

<!DOCTYPE html>
<html lang="en">
<head>
    <title>Memory leaks</title>
</head>
<body>
<button id="print">Print Numbers</button>
<button id="clear">Clear</button>
</body>
</html>
<script>
    var longArray = [];

    function print() {
      for (var i = 0; i < 10000; i++) {
          let paragraph = document.createElement("p");
          paragraph.innerHTML = i;
         document.body.appendChild(paragraph);
      }
      longArray.push(new Array(1000000).join("y"));
    }

    document.getElementById("print").addEventListener("click", print);
    document.getElementById("clear").addEventListener("click", () => {
      window.longArray = null;
      document.body.innerHTML = "Cleared";
    });
</script>

Al analizar la captura de pantalla a continuación, que es la línea de tiempo de rendimiento para el fragmento de código anterior, podemos ver que el montón de JavaScript de color azul aumenta con cada clic en el botón Imprimir . Estos picos son naturales porque JavaScript crea los nodos DOM y agrega caracteres a la matriz global.

El montón de JavaScript aumentó gradualmente con cada clic en el botón Imprimir y se volvió normal después del clic en el botón Borrar . En un escenario de palabras reales, puede considerar que hay una pérdida de memoria si observa un pico continuo en la memoria y si no hay una disminución en el consumo de memoria.

Por otro lado, podemos observar el aumento continuo en la cantidad de nodos, que se muestra en el gráfico verde, ya que no los eliminamos:

Identificar nodos DOM separados

Como discutimos anteriormente, se dice que un nodo se desconecta cuando se elimina del árbol DOM, pero algunos códigos de JavaScript todavía hacen referencia a él.

Inspeccionemos los nodos DOM separados con el fragmento de código a continuación. Con el clic de un botón, podemos agregar elementos de la lista a su padre y asignar el padre a una variable global. En términos simples, la variable global contiene las referencias DOM:

var detachedElement;
function createList(){
    let ul = document.createElement("ul");
    for(let i=0; i<5; i++){
        ul.appendChild(document.createElement("li"));
    }
    detachedElement = ul;
}
document.getElementById("createList").addEventListener("click", createList);

Podemos usar una instantánea de montón para detectar nodos DOM separados. Vaya a Chrome DevToolsMemoriaHeap SnapshotTomar instantánea :

Una vez que se hace clic en el botón, tome la instantánea. Puede encontrar nodos DOM separados filtrando Detacheden la sección de resumen, como se muestra a continuación:

Exploramos los nodos fuera del DOM usando Chrome DevTools. Puede intentar identificar otras fugas de memoria utilizando este método.

Conclusión

En este tutorial, aprendimos sobre las fugas de memoria, cómo prevenirlas y cómo detectarlas con Chrome DevTools.

Las fugas de memoria a menudo se deben a fallas en su lógica. Evitar todas las fugas posibles puede mejorar significativamente el rendimiento de su aplicación y ahorrar memoria. ¡Espero que hayas disfrutado este tutorial y feliz codificación!

Fuente: https://blog.logrocket.com/escape-memory-leaks-javascript/

#javascript 

What is GEEK

Buddha Community

Cómo Escapar De Las Fugas De Memoria En JavaScript

Cómo Escapar De Las Fugas De Memoria En JavaScript

Si su aplicación de JavaScript experimenta fallas frecuentes, alta latencia y bajo rendimiento, una posible causa podría ser la pérdida de memoria. Los desarrolladores a menudo descuidan la gestión de la memoria debido a conceptos erróneos sobre la asignación automática de memoria por parte de los motores de JavaScript, lo que provoca fugas de memoria y un rendimiento deficiente.

En este artículo, exploraremos la administración de memoria, los tipos de fugas de memoria y la búsqueda de fugas de memoria en JavaScript usando Chrome DevTools. ¡Empecemos!

¿Qué son las fugas de memoria?

En palabras simples, una fuga de memoria es una porción de memoria asignada que el motor de JavaScript no puede recuperar. El motor de JavaScript asigna memoria cuando crea objetos y variables en su aplicación, y es lo suficientemente inteligente como para borrar la memoria cuando ya no necesita los objetos. Las fugas de memoria se deben a fallas en su lógica y dan lugar a un rendimiento deficiente en su aplicación.

Antes de saltar a los diferentes tipos de fugas de memoria, tengamos una idea clara de la gestión de memoria en JavaScript, la recolección de elementos no utilizados .

Ciclo de vida de la memoria

En cualquier lenguaje de programación, el ciclo de vida de la memoria consta de tres pasos:

Asignación de memoria

El sistema operativo asigna memoria al programa durante la ejecución según sea necesario.

Usar memoria

Su programa usa memoria previamente asignada. Su programa puede realizar ready writeacciones en la memoria.

Liberar memoria

Una vez que finaliza su tarea, la memoria asignada se libera y queda libre. En lenguajes de alto nivel como JavaScript, el recolector de basura maneja la liberación de memoria. Si comprende cómo ocurre la asignación y liberación de memoria en JavaScript, es muy fácil resolver las fugas de memoria en su aplicación.

Asignación de memoria

JavaScript tiene dos opciones de almacenamiento para la asignación de memoria. Uno es la pila y el otro es el montón. Todos los tipos primitivos, como number, Booleano undefinedse almacenarán en la pila. Heap es el lugar para tipos de referencia como objetos, matrices y funciones.

Pila

Stack sigue el enfoque FIFO para asignar memoria. Todos los tipos primitivos como number, Booleany undefinedse pueden almacenar en la pila:

 

Montón

Los tipos de referencia como objetos, matrices y funciones se almacenan en el montón. El tamaño de los tipos de referencia no se puede determinar en el momento de la compilación, por lo que la memoria se asigna en función del uso de los objetos. La referencia del objeto se almacena en la pila y el objeto real se almacena en el montón:

En la imagen de arriba, la otherStudentvariable se crea copiando la variable del estudiante. En este escenario, otherStudentse crea en la pila, pero apunta a la referencia del estudiante en el montón.

Hemos visto que el principal desafío para la asignación de memoria en el ciclo de memoria es cuándo liberar la memoria asignada y hacerla disponible para otros recursos. En este escenario, la recolección de basura viene al rescate.

Recolector de basura

La causa principal de las fugas de memoria en una aplicación se debe a las referencias no deseadas. El recolector de elementos no utilizados encuentra la memoria que el programa ya no utiliza y la vuelve a liberar al sistema operativo para su asignación adicional.

Para saber qué es una referencia no deseada, primero, debemos tener una idea de cómo la recolección de basura determina que una parte de la memoria es inalcanzable. La recolección de basura utiliza dos algoritmos principales para encontrar referencias no deseadas y código inalcanzable, recuento de referencias y marcado y barrido.

Recuento de referencia

El algoritmo de recuento de referencias busca objetos que no tienen referencias. Un objeto puede liberarse si no tiene referencias que lo apunten.

Entendamos esto mejor con el siguiente ejemplo. Hay tres variables, student, otherStudent, que es una copia de estudiante, y sports, que toma la matriz de deportes del studentobjeto:

let student = {
    name: 'Joe',
    age: 15,
    sports: ['soccer', 'chess']
}
let otherStudent = student;
const sports = student.sports;
student = null;
otherStudent = null;

En el fragmento de código anterior, asignamos studenty otherStudentvariables a valores nulos, lo que nos dice que estos objetos no tienen referencias a ellos. La memoria que se les asigna en el montón, que está en rojo, se puede liberar fácilmente ya que no tiene referencias.

Por otro lado, tenemos otro bloque de memoria en el montón, que no se puede liberar porque tiene la sportsreferencia al objeto.

Cuando dos objetos se refieren a sí mismos, hay un problema con el algoritmo de recuento de referencias. En términos simples, si hay referencias cíclicas, este algoritmo falla en determinar objetos libres.

En el siguiente ejemplo, personse asignó a employeey employeea person, por lo que estos objetos se refieren entre sí:

let person = {
    name: 'Joe'
};
let employee = {
    id: 123
};
person.employee = employee;
employee.person = person;
person = null;
employee = null;

Después de crear estos objetos null, perderán la referencia en la pila, pero los objetos permanecerán en el montón ya que tienen la referencia cíclica. El algoritmo de referencia no pudo liberar estos objetos ya que tienen una referencia. El problema de referencia cíclica se puede resolver usando el algoritmo de marcar y barrer.

algoritmo de marcar y barrer

El algoritmo de marcar y barrer reduce la definición de un objeto innecesario a un objeto inalcanzable. Si el objeto no es accesible, el algoritmo considera que este objeto es innecesario:

El algoritmo de marcar y barrer sigue dos pasos. Primero, en JavaScript, la raíz es el objeto global. El recolector de elementos no utilizados comienza periódicamente desde la raíz y encuentra todos los objetos a los que se hace referencia desde la raíz. Marcará todos los objetos alcanzables active. Luego, la recolección de basura libera la memoria para todos los objetos que no están marcados como active, devolviendo la memoria al sistema operativo.

Tipos de fugas de memoria

Podemos evitar las fugas de memoria si comprendemos cómo se crean las referencias no deseadas en JavaScript. Los siguientes escenarios provocan referencias no deseadas.

Variables globales accidentales o no declaradas

Una de las formas en que JavaScript es permisivo es en la forma en que maneja las variables no declaradas. Una referencia a una variable no declarada crea una nueva variable dentro del objeto global. Si crea una variable sin ninguna referencia, su raíz sería el objeto global.

Como acabamos de ver en el algoritmo de marcar y barrer, las referencias que apuntan directamente a la raíz siempre son active, y el recolector de basura no puede borrarlas, lo que genera una pérdida de memoria:

function foo(){
    this.message = 'I am accidental variable';
}
foo();

Como solución, intente anular estas variables después de su uso, o agregue use strictpara habilitar un modo más estricto de JavaScript que evite las variables globales accidentales.

Cierres

Un cierre es una combinación de una función agrupada o encerrada con referencias a su estado circundante, el entorno léxico. En términos simples, un cierre es una función interna que tiene acceso al alcance de la función externa.

Las variables del ámbito de la función se limpian después de que la función haya salido de la pila de llamadas, mientras que un cierre mantiene las variables del ámbito externo a las que se hace referencia después de su ejecución. Las variables de alcance externo residen en la memoria aunque no se utilicen, por lo que esta es una causa común de fugas de memoria:

function outer(){
    const largeArray = []; // unused array
    return function inner(num){
        largeArray.push(num);
    }
}
const appendNumbers = outer(); // get the inner function
// call the inner function repeatedly
for (let i=0; i< 100000000; i++){
    appendNumbers(i);
}

En el ejemplo anterior, largeArraynunca se devuelve y el recolector de basura no puede acceder a él, lo que aumenta significativamente su tamaño a través de llamadas repetidas de funciones internas, lo que resulta en una pérdida de memoria.

Los cierres son inevitables, así que asegúrese de que las variables en el ámbito externo se usen o se devuelvan.

Temporizadores olvidados

setTimeouty setIntervalson los dos eventos de temporización disponibles en JavaScript. La setTimeoutfunción se ejecuta cuando transcurre el tiempo dado, mientras que setIntervalse ejecuta repetidamente durante el intervalo de tiempo dado. Estos temporizadores son la causa más común de pérdidas de memoria.

Si configuramos el temporizador recurrente en nuestro código, la referencia al objeto de la devolución de llamada del temporizador permanece activa hasta que el temporizador se detiene:

function generateRandomNumbers(){
    const numbers = []; // huge increasing array
    return function(){
        numbers.push(Math.random());
    }
}
setInterval((generateRandomNumbers(), 2000));

En el ejemplo anterior, generateRandomNumbersdevuelve una función que agrega números aleatorios a la matriz de números de alcance externo. Al usar setIntervalesta función, llama al intervalo especificado periódicamente y da como resultado un tamaño enorme para la matriz de números.

Para resolver este problema, las mejores prácticas requieren proporcionar referencias dentro de las llamadas setTimeoutor . setIntervalLuego, haga una llamada explícita para borrar los temporizadores. Para el ejemplo anterior, la solución es la siguiente:

const timer = setInterval(generateRandomNumbers(), 2000); // save the timer
    // on any event like button click or mouse over etc
    clearInterval(timer); // stop the timer

Fuera de referencia DOM

Fuera de la referencia DOM indica nodos que se han eliminado del DOM pero que aún están disponibles en la memoria. El recolector de elementos no utilizados no puede liberar estos objetos DOM, ya que se denominan memoria gráfica de objetos. Entendamos esto con un ejemplo a continuación:

let parent = document.getElementById("#parent");
let child = document.getElementById("#child");
parent.addEventListener("click", function(){
    child.remove(); // removed from the DOM but not from the object memory
});

En el código anterior, eliminamos el elemento secundario del DOM al hacer clic en el principal, pero la variable secundaria aún contiene la memoria porque el detector de eventos siempre es active, y contiene la referencia secundaria. Por este motivo, el recolector de elementos no utilizados no puede liberar el objeto secundario y seguirá consumiendo la memoria.

Siempre debe anular el registro de los detectores de eventos una vez que ya no los necesite creando la referencia para el detector de eventos y pasándola al removeEventListenermétodo:

function removeChild(){
    child.remove();
}
parent.addEventListener("click", removeChild);
// after completing required action
parent.removeEventListener("click", removeChild);

Identifique fugas de memoria con Chrome DevTools

La depuración de problemas de memoria es realmente un trabajo difícil, pero podemos identificar el gráfico de memoria y algunas fugas de memoria con Chrome DevTools. Nos centraremos en dos aspectos importantes de nuestra vida diaria como desarrolladores:

  1. Visualice el consumo de memoria con el generador de perfiles de rendimiento
  2. Identifique los nodos DOM separados.

Visualice el consumo de memoria con el generador de perfiles de rendimiento

Consideremos el siguiente fragmento de código como ejemplo. Hay dos botones, Print Numbersy Clear. Con un clic en el botón Imprimir números , los números desde 1hasta 10,000se agregan al DOM creando nodos de párrafo y empujando algunas cadenas enormes a la variable global.

El botón Borrar borrará la variable global y anulará el cuerpo del documento, pero no eliminará los nodos creados al hacer clic en Imprimir :

<!DOCTYPE html>
<html lang="en">
<head>
    <title>Memory leaks</title>
</head>
<body>
<button id="print">Print Numbers</button>
<button id="clear">Clear</button>
</body>
</html>
<script>
    var longArray = [];

    function print() {
      for (var i = 0; i < 10000; i++) {
          let paragraph = document.createElement("p");
          paragraph.innerHTML = i;
         document.body.appendChild(paragraph);
      }
      longArray.push(new Array(1000000).join("y"));
    }

    document.getElementById("print").addEventListener("click", print);
    document.getElementById("clear").addEventListener("click", () => {
      window.longArray = null;
      document.body.innerHTML = "Cleared";
    });
</script>

Al analizar la captura de pantalla a continuación, que es la línea de tiempo de rendimiento para el fragmento de código anterior, podemos ver que el montón de JavaScript de color azul aumenta con cada clic en el botón Imprimir . Estos picos son naturales porque JavaScript crea los nodos DOM y agrega caracteres a la matriz global.

El montón de JavaScript aumentó gradualmente con cada clic en el botón Imprimir y se volvió normal después del clic en el botón Borrar . En un escenario de palabras reales, puede considerar que hay una pérdida de memoria si observa un pico continuo en la memoria y si no hay una disminución en el consumo de memoria.

Por otro lado, podemos observar el aumento continuo en la cantidad de nodos, que se muestra en el gráfico verde, ya que no los eliminamos:

Identificar nodos DOM separados

Como discutimos anteriormente, se dice que un nodo se desconecta cuando se elimina del árbol DOM, pero algunos códigos de JavaScript todavía hacen referencia a él.

Inspeccionemos los nodos DOM separados con el fragmento de código a continuación. Con el clic de un botón, podemos agregar elementos de la lista a su padre y asignar el padre a una variable global. En términos simples, la variable global contiene las referencias DOM:

var detachedElement;
function createList(){
    let ul = document.createElement("ul");
    for(let i=0; i<5; i++){
        ul.appendChild(document.createElement("li"));
    }
    detachedElement = ul;
}
document.getElementById("createList").addEventListener("click", createList);

Podemos usar una instantánea de montón para detectar nodos DOM separados. Vaya a Chrome DevToolsMemoriaHeap SnapshotTomar instantánea :

Una vez que se hace clic en el botón, tome la instantánea. Puede encontrar nodos DOM separados filtrando Detacheden la sección de resumen, como se muestra a continuación:

Exploramos los nodos fuera del DOM usando Chrome DevTools. Puede intentar identificar otras fugas de memoria utilizando este método.

Conclusión

En este tutorial, aprendimos sobre las fugas de memoria, cómo prevenirlas y cómo detectarlas con Chrome DevTools.

Las fugas de memoria a menudo se deben a fallas en su lógica. Evitar todas las fugas posibles puede mejorar significativamente el rendimiento de su aplicación y ahorrar memoria. ¡Espero que hayas disfrutado este tutorial y feliz codificación!

Fuente: https://blog.logrocket.com/escape-memory-leaks-javascript/

#javascript 

Rahul Jangid

1622207074

What is JavaScript - Stackfindover - Blog

Who invented JavaScript, how it works, as we have given information about Programming language in our previous article ( What is PHP ), but today we will talk about what is JavaScript, why JavaScript is used The Answers to all such questions and much other information about JavaScript, you are going to get here today. Hope this information will work for you.

Who invented JavaScript?

JavaScript language was invented by Brendan Eich in 1995. JavaScript is inspired by Java Programming Language. The first name of JavaScript was Mocha which was named by Marc Andreessen, Marc Andreessen is the founder of Netscape and in the same year Mocha was renamed LiveScript, and later in December 1995, it was renamed JavaScript which is still in trend.

What is JavaScript?

JavaScript is a client-side scripting language used with HTML (Hypertext Markup Language). JavaScript is an Interpreted / Oriented language called JS in programming language JavaScript code can be run on any normal web browser. To run the code of JavaScript, we have to enable JavaScript of Web Browser. But some web browsers already have JavaScript enabled.

Today almost all websites are using it as web technology, mind is that there is maximum scope in JavaScript in the coming time, so if you want to become a programmer, then you can be very beneficial to learn JavaScript.

JavaScript Hello World Program

In JavaScript, ‘document.write‘ is used to represent a string on a browser.

<script type="text/javascript">
	document.write("Hello World!");
</script>

How to comment JavaScript code?

  • For single line comment in JavaScript we have to use // (double slashes)
  • For multiple line comments we have to use / * – – * /
<script type="text/javascript">

//single line comment

/* document.write("Hello"); */

</script>

Advantages and Disadvantages of JavaScript

#javascript #javascript code #javascript hello world #what is javascript #who invented javascript

Hire Dedicated JavaScript Developers -Hire JavaScript Developers

It is said that a digital resource a business has must be interactive in nature, so the website or the business app should be interactive. How do you make the app interactive? With the use of JavaScript.

Does your business need an interactive website or app?

Hire Dedicated JavaScript Developer from WebClues Infotech as the developer we offer is highly skilled and expert in what they do. Our developers are collaborative in nature and work with complete transparency with the customers.

The technology used to develop the overall app by the developers from WebClues Infotech is at par with the latest available technology.

Get your business app with JavaScript

For more inquiry click here https://bit.ly/31eZyDZ

Book Free Interview: https://bit.ly/3dDShFg

#hire dedicated javascript developers #hire javascript developers #top javascript developers for hire #hire javascript developer #hire a freelancer for javascript developer #hire the best javascript developers

joe biden

1617257581

Software de restauración de Exchange para restaurar sin problemas PST en Exchange Server

¿Quiere restaurar los buzones de correo de PST a Exchange Server? Entonces, estás en la página correcta. Aquí, lo guiaremos sobre cómo puede restaurar fácilmente mensajes y otros elementos de PST a MS Exchange Server.

Muchas veces, los usuarios necesitan restaurar los elementos de datos de PST en Exchange Server, pero debido a la falta de disponibilidad de una solución confiable, los usuarios no pueden obtener la solución. Háganos saber primero sobre el archivo PST y MS Exchange Server.

Conozca PST y Exchange Server

PST es un formato de archivo utilizado por MS Outlook, un cliente de correo electrónico de Windows y muy popular entre los usuarios domésticos y comerciales.

Por otro lado, Exchange Server es un poderoso servidor de correo electrónico donde todos los datos se almacenan en un archivo EDB. Los usuarios generalmente guardan la copia de seguridad de los buzones de correo de Exchange en el archivo PST, pero muchas veces, los usuarios deben restaurar los datos del archivo PST en Exchange. Para resolver este problema, estamos aquí con una solución profesional que discutiremos en la siguiente sección de esta publicación.

Un método profesional para restaurar PST a Exchange Server

No le recomendamos que elija una solución al azar para restaurar los datos de PST en Exchange Server. Por lo tanto, al realizar varias investigaciones, estamos aquí con una solución inteligente y conveniente, es decir, Exchange Restore Software. Es demasiado fácil de manejar por todos los usuarios y restaurar cómodamente todos los datos del archivo PST a Exchange Server.

Funciones principales ofrecidas por Exchange Restore Software

El software es demasiado simple de usar y se puede instalar fácilmente en todas las versiones de Windows. Con unos pocos clics, la herramienta puede restaurar los elementos del buzón de Exchange.

No es necesario que MS Outlook restaure los datos PST en Exchange. Todos los correos electrónicos, contactos, notas, calendarios, etc. se restauran desde el archivo PST a Exchange Server.

Todas las versiones de Outlook son compatibles con la herramienta, como Outlook 2019, 2016, 2013, 2010, 2007, etc. La herramienta proporciona varios filtros mediante los cuales se pueden restaurar los datos deseados desde un archivo PST a Exchange Server. El programa se puede instalar en todas las versiones de Windows como Windows 10, 8.1, 8, 7, XP, Vista, etc.

Descargue la versión de demostración del software de restauración de Exchange y analice el funcionamiento del software restaurando los primeros 50 elementos por carpeta.

Líneas finales

No existe una solución manual para restaurar los buzones de correo de Exchange desde el archivo PST. Por lo tanto, hemos explicado una solución fácil e inteligente para restaurar datos de archivos PST en Exchange Server. Simplemente puede usar este software y restaurar todos los datos de PST a Exchange Server.

Más información:- https://www.datavare.com/software/exchange-restore.html

#intercambio de software de restauración #intercambio de restauración #buzón del servidor de intercambio #herramienta de restauración de intercambio

Niraj Kafle

1589255577

The essential JavaScript concepts that you should understand

As a JavaScript developer of any level, you need to understand its foundational concepts and some of the new ideas that help us developing code. In this article, we are going to review 16 basic concepts. So without further ado, let’s get to it.

#javascript-interview #javascript-development #javascript-fundamental #javascript #javascript-tips