Terminología de memoria

Los términos siguientes se usan en la herramienta Memoria , que es para investigar problemas de memoria. Estos términos de memoria se aplican al análisis de memoria en general, así como a las herramientas de generación de perfiles de memoria para lenguajes como Java o .NET.

Para más información sobre el uso de la herramienta Memoria , consulte Registro de instantáneas de montón mediante la herramienta Memoria.

Gráfico de memoria

Piense en la memoria que usa una página web como un gráfico: una estructura que contiene nodos que están conectados entre sí por bordes:

Representación visual de la memoria

Los nodos del gráfico de memoria representan los objetos utilizados por la página, incluidos los tipos primitivos, como números o cadenas de JavaScript, y objetos como matrices asociativas. A los nodos y bordes del gráfico de memoria se les proporcionan las siguientes etiquetas:

  • Los nodos (u objetos) se etiquetan con el nombre de la función de constructor que se usó para compilarlos.

  • Los bordes se etiquetan con los nombres de las propiedades.

Un nodo del gráfico puede contener memoria de dos maneras:

  • Directamente; el propio objeto mantiene la memoria.

  • Implícitamente, al contener referencias a otros objetos. Un objeto que contiene referencias a otros objetos impide que la recolección de elementos no utilizados (GC) elimine automáticamente esos objetos.

Memoria del montón y del representador de JavaScript

El montón de JavaScript es una región de memoria en el proceso del explorador donde residen todos los objetos JavaScript y WebAssembly. El montón de JavaScript también se denomina memoria V8 (después del motor de JavaScript V8 que alimenta Microsoft Edge).

El montón de JavaScript forma parte de la memoria del representador. La memoria del representador es la memoria utilizada por el proceso del explorador donde se representa la página web. La memoria del representador se compone de lo siguiente:

  • Memoria nativa, como la memoria que usan los objetos de C++ que representan los nodos DOM.
  • Memoria del montón de JavaScript de la página.
  • Memoria del montón de JavaScript de todos los trabajos dedicados iniciados por la página.

La herramienta Memoria muestra lo siguiente:

  • Memoria V8.
  • Los objetos asignados en la memoria nativa que son relevantes para la página web representada.

Raíces de recolección de elementos no utilizados

El explorador crea raíces de recolección de elementos no utilizados (raíces de GC) cuando se hace una referencia desde el código nativo del explorador a un objeto JavaScript que está fuera de la máquina virtual V8. Estas referencias se denominan identificadores.

Hay muchas raíces de GC internas, la mayoría de las cuales no son interesantes para los desarrolladores web. Desde el punto de vista de la página web, existen los siguientes tipos de raíces de GC:

  • Objetos globales de ventana (uno en cada iframe).

  • A veces, los objetos se conservan mediante el contexto de depuración establecido por la herramienta Sources o Console , como al evaluar una expresión de JavaScript en la herramienta Consola . Para quitar estos objetos de la herramienta Memoria , antes de grabar una instantánea del montón, borre la herramienta Consola y desactive los puntos de interrupción en la herramienta Orígenes .

El gráfico de memoria comienza con una raíz de GC, que puede ser el window objeto del explorador o el Global objeto de un módulo de Node.js. No se controla cómo se recopila el objeto raíz como elemento no utilizado:

No se puede controlar cómo se recopila el objeto raíz como elemento no utilizado

Los nodos a los que no se puede acceder desde la raíz pueden obtener recolección de elementos no utilizados.

Tamaños y distancias de objetos

Al trabajar con la herramienta Memoria , es probable que se encuentre mirando las siguientes columnas de información:

  • Distancia
  • Tamaño superficial
  • Tamaño retenido

Las columnas Distancia, Tamaño superficial y Tamaño retenido de la herramienta Memoria

Los números de las columnas Tamaño superficial y Tamaño retenido son el número de bytes.

Distancia

La distancia de un objeto en el montón de JavaScript es el número de nodos en la ruta de acceso más corta entre el objeto y la raíz de GC. Cuanto menor sea la distancia, más probable es que este objeto desempeña un papel importante en el uso de memoria de la página web.

Tamaño superficial

El tamaño superficial es el tamaño del montón de JavaScript que contiene directamente un objeto. El tamaño superficial de un objeto suele ser pequeño, ya que un objeto De JavaScript a menudo solo almacena su descripción del objeto, no los valores, en la memoria que contiene directamente el objeto. La mayoría de los objetos JavaScript almacenan sus valores en un almacén de respaldo que se encuentra en otra parte del montón de JavaScript y solo exponen un pequeño objeto contenedor en la parte del montón de JavaScript que es propiedad directa del objeto.

A partir de Microsoft Edge 123, la herramienta Memoria se puede configurar para notificar el tamaño total de memoria de los objetos en lugar de solo el tamaño de memoria que contienen directamente. Para obtener más información, consulte Configuración de la columna Tamaño superficial para incluir el tamaño de un objeto completo en Registro de instantáneas de montón mediante la herramienta Memoria.

Sin embargo, incluso un objeto pequeño puede contener una gran cantidad de memoria indirectamente, evitando que el proceso de recolección de elementos no utilizados elimine otros objetos.

Tamaño retenido

El tamaño retenido es el tamaño de la memoria que un objeto mantiene implícitamente y que podría liberarse una vez que se eliminen el objeto y otros retenes existentes junto con todos los objetos dependientes a los que no se pudo acceder desde las raíces de GC.

Es decir, el tamaño retenido de un objeto es la cantidad de memoria que se recuperaría si el objeto y todos sus objetos dependientes se quitaran del gráfico de memoria.

El tamaño retenido no puede ser menor que el tamaño superficial.

Cuando varios nodos conservan un objeto, el tamaño del objeto aparece en el tamaño retenido del nodo de retención que tiene la ruta de acceso más corta a la raíz de GC.

Retenedores

Los retenes de un objeto son los demás objetos que contienen referencias al objeto . La sección Retenes de la herramienta Memoria muestra los objetos que contienen referencias al objeto seleccionado en la vista Resumen .

La sección Retenedores de la herramienta Memoria se ordena por distancia de forma predeterminada, lo que significa que primero se muestran las rutas de acceso de retención más sencillas para un objeto.

El recolector de elementos no utilizados del explorador puede descartar cualquier objeto sin retenes, lo que reduce el uso de memoria.

Detalles de V8

Al generar perfiles de memoria, resulta útil comprender por qué las instantáneas del montón tienen un aspecto determinado. En esta sección se describe cómo la máquina virtual JavaScript V8 almacena algunos objetos en memoria (abreviado aquí como máquina virtual V8 o simplemente máquina virtual), lo que puede ayudarle al analizar instantáneas de montón en la herramienta Memoria .

Primitivos de JavaScript

En JavaScript, hay varios tipos primitivos, como:

  • Números (como 3.14159).
  • Booleanos (true o false).
  • Cadenas (como "Werner Heisenberg").

Los primitivos no pueden hacer referencia a otros valores y siempre son nodos hoja (también denominados nodos de terminación) en el gráfico de memoria.

Los números se pueden almacenar como:

  • Valores enteros inmediatos de 31 bits que se denominan enteros pequeños (SMI).

  • Objetos de montón, a los que se hace referencia como números de montón. Los números de montón se usan para almacenar valores que no caben en el formulario de entero pequeño (SMI), como valores de tipo doubleo cuando es necesario incluir un valor en la caja, como establecer propiedades en él.

Las cadenas se pueden almacenar en:

  • El montón de máquinas virtuales.

  • Externamente en la memoria del representador. Se crea un objeto contenedor y se usa para acceder al almacenamiento externo donde, por ejemplo, se almacenan los orígenes de script y otro contenido que se recibe de la Web, en lugar de copiarse en el montón de máquinas virtuales.

Objetos JavaScript

La memoria de los nuevos objetos de JavaScript se asigna desde un montón de JavaScript dedicado (o un montón de máquinas virtuales). Estos objetos se administran mediante el recolector de elementos no utilizados de la máquina virtual V8 y, por lo tanto, estos objetos permanecen activos mientras haya al menos una referencia a ellos.

Otros objetos

  • Objetos nativos: todo lo que no esté almacenado en el montón de JavaScript se denomina objeto nativo. Un objeto nativo, a diferencia de un objeto de montón, no está administrado por el recolector de elementos no utilizados V8 a lo largo de su duración y solo se puede acceder a él desde JavaScript mediante su objeto contenedor de JavaScript.

  • Cadenas concatenadas: las cadenas que se almacenan y, a continuación, se unen, como resultado de una concatenación de cadenas en JavaScript, se almacenan como cadenas concatenadas en V8. La unión del contenido de la cadena solo se produce según sea necesario, como cuando es necesario construir una subcadena de una cadena combinada.

    Por ejemplo, si concatena a y b, obtiene una cadena (a, b) concatenada que representa el resultado de la concatenación. Si más adelante concatena c con ese resultado, obtendrá otra cadena concatenada: ((a, b), c).

  • Matrices: una matriz es un objeto que tiene claves numéricas. Las matrices se usan ampliamente en la máquina virtual V8 para almacenar grandes cantidades de datos. Los conjuntos de pares clave-valor que se usan como diccionarios se implementan como matrices.

    Un objeto JavaScript típico se almacena como solo uno de los dos tipos de matriz:

    • Matriz para almacenar propiedades con nombre.
    • Matriz para almacenar elementos numéricos.

    Cuando hay un pequeño número de propiedades, las propiedades se almacenan internamente en el objeto JavaScript.

  • system/Map: objeto que describe tanto el tipo de objeto que es como el diseño. Por ejemplo, los objetos system/Map se usan para describir jerarquías de objetos implícitas para un acceso rápido a las propiedades. Consulte Propiedades rápidas en V8.

Nota:

Las partes de esta página son modificaciones basadas en el trabajo creado y compartido por Google y usadas según los términos descritos en la licencia internacional creative Commons Attribution 4.0. La página original se encuentra aquí y está creada por Meggin Kearney (Escritor técnico).

Licencia de Creative Commons Esta obra está licenciada bajo una Licencia Internacional Creative Commons Attribution 4.0.