En este artículo, se presenta el Inspector de memoria que se lanzó en Chrome 91. Te permite inspeccionar tu ArrayBuffer, TypedArray, DataView y memoria Wasm.
Introducción
¿Alguna vez quisiste entender los datos de tu ArrayBuffer? Antes del Inspector de memoria, DevTools solo permitía estadísticas limitadas sobre los ArrayBuffers. La inspección de la vista Scope durante una sesión de depuración se limitaba a ver una lista de valores individuales dentro del búfer de array, lo que dificultaba comprender los datos en su totalidad. A modo de ejemplo, la vista Alcance muestra el búfer como rangos expandibles de arrays en el siguiente ejemplo:
Navegar a un rango determinado dentro del búfer era un problema, ya que el usuario debía desplazarse hacia abajo para llegar a ese índice. Sin embargo, incluso si navegar a una posición fuera fácil, esta forma de inspeccionar los valores es engorrosa: es difícil saber qué significan estos números. En especial, ¿qué sucede si no se deben interpretar como bytes individuales, sino, por ejemplo, como números enteros de 32 bits?
Cómo inspeccionar valores con el Inspector de memoria
Con Chrome 91, presentamos el Inspector de memoria, una herramienta para inspeccionar los búferes de array. Es posible que hayas visto herramientas de inspección de memoria para ver datos binarios, que muestran el contenido binario en una cuadrícula junto con sus direcciones y que ofrecen diferentes formas de interpretar los valores subyacentes. Esto es lo que te ofrece el Inspector de memoria. Con el Inspector de memoria, ahora puedes ver el contenido, navegar por él y seleccionar los tipos que se usarán para interpretar los valores en cuestión. Muestra los valores ASCII directamente junto a los bytes y permite que el usuario seleccione diferentes ordenes de bytes. Consulta el Inspector de memoria en acción a continuación:
¿Quieres probarlo? Para obtener información sobre cómo abrir el Inspector de memoria y ver tu búfer de array (o TypedArray, DataView o memoria Wasm) y más información sobre cómo usarlo, consulta nuestra documentación sobre el Inspector de memoria. Pruébala en estos ejemplos de juguete (para JS, Wasm y C++).
Cómo diseñar el Inspector de memoria
En esta parte, veremos cómo se diseñó el Inspector de memoria con componentes web y mostraremos uno de los objetivos de diseño que teníamos y cómo lo implementamos. Si tienes curiosidad y quieres ver más, consulta nuestra documentación de diseño del Inspector de memoria.
Es posible que hayas visto nuestra entrada de blog sobre cómo migrar a componentes web, en la que Jack publicó nuestra guía interna sobre cómo compilar componentes de IU con componentes web. La migración a los componentes web coincidió con nuestro trabajo en el Inspector de memoria y, como resultado, decidimos probar el nuevo sistema. A continuación, se muestra un diagrama que muestra los componentes que compilamos para crear el Inspector de memoria (ten en cuenta que, de forma interna, lo llamamos Inspector de memoria lineal):
El componente LinearMemoryInspector
es el componente superior que combina los subcomponentes que compilan todos los elementos del Inspector de memoria. Básicamente, toma un Uint8Array
y un address
, y en cada cambio de cualquiera de ellos, propaga los datos a sus elementos secundarios, lo que activa una nueva renderización. El LinearMemoryInspector
renderiza tres subcomponentes:
LinearMemoryViewer
(muestra los valores)LinearMemoryNavigator
(permite la navegación).LinearMemoryValueInterpreter
(que muestra diferentes interpretaciones de tipo de los datos subyacentes).
Este último es, en sí, un componente superior, que renderiza ValueInterpreterDisplay
(muestra los valores) y ValueInterpreterSettings
(selecciona qué tipos se verán en la pantalla).
Cada uno de los componentes está diseñado para representar solo un componente pequeño de la IU, de modo que los componentes se puedan volver a usar si es necesario. Cada vez que se establecen datos nuevos en un componente, se activa una nueva renderización, que muestra el cambio reflejado en los datos establecidos en el componente. A continuación, se muestra un ejemplo de un flujo de trabajo con nuestros componentes, en el que el usuario cambia la dirección en la barra de direcciones, lo que activa una actualización configurando los datos nuevos, en este caso, la dirección que se mostrará:
LinearMemoryInspector
se agrega como objeto de escucha en LinearMemoryNavigator
. La función addressChanged
se activará en un evento address-changed
. En cuanto el usuario edita la entrada de dirección, se envía el evento mencionado anteriormente, de modo que se llame a la función addressChanged
. Esta función ahora guarda la dirección de forma interna y actualiza sus subcomponentes con un set data(address, ..)
. Los subcomponentes guardan la dirección de forma interna y vuelven a renderizar sus vistas, lo que muestra el contenido en esa dirección en particular.
Objetivo de diseño: hacer que el rendimiento y el consumo de memoria sean independientes del tamaño del búfer
Un aspecto que tuvimos en cuenta durante el diseño del Inspector de memoria fue que el rendimiento del Inspector de memoria debería ser independiente del tamaño del búfer.
Como viste en la parte anterior, el componente LinearMemoryInspector
toma un UInt8Array
para renderizar los valores. Al mismo tiempo, queríamos asegurarnos de que el Inspector de memoria no necesitara conservar todos los datos, ya que solo muestra una parte (p.ej., la memoria de Wasm puede ser de hasta 4 GB, y no queremos almacenar 4 GB en el Inspector de memoria).
Por lo tanto, para garantizar que la velocidad y el consumo de memoria del Inspector de memoria sean independientes del búfer real que mostramos, permitimos que el componente LinearMemoryInspector
solo mantenga un subrango del búfer original.
Para que esto funcione, LinearMemoryInspector
primero debe tomar dos argumentos más: un memoryOffset
y un outerMemoryLength
. memoryOffset
indica el desplazamiento, en el que comienza el Uint8Array pasado, y es necesario para renderizar las direcciones de datos correctas. outerMemoryLength
es la longitud del búfer original y es necesaria para comprender qué rango podemos mostrar:
Con esta información, podemos asegurarnos de poder renderizar la misma vista que antes (el contenido alrededor de address
), sin tener todos los datos en su lugar. Entonces, ¿qué se debe hacer si se solicita una dirección diferente, que pertenece a un rango diferente? En ese caso, LinearMemoryInspector
activa un RequestMemoryEvent
, que actualiza el rango actual que se mantiene. A continuación, se muestra un ejemplo:
En este ejemplo, el usuario navega por la página de memoria (el Inspector de memoria usa la paginación para mostrar fragmentos de datos), lo que activa un PageNavigationEvent
, que a su vez activa un RequestMemoryEvent
.
Ese evento inicia la recuperación del nuevo rango, que luego se propaga al componente LinearMemoryInspector
a través de la configuración de los datos. Como resultado, mostramos los datos recuperados recientemente.
¿Sabías que…? Incluso puedes inspeccionar la memoria en el código Wasm y C/C++.
El Inspector de memoria no solo está disponible para ArrayBuffers
en JavaScript, sino que también se puede usar para inspeccionar la memoria de Wasm y la memoria a la que apuntan las referencias o punteros de C/C++ (con nuestra extensión DWARF, pruébala si aún no lo has hecho). Consulta Cómo depurar WebAssembly con herramientas modernas aquí. Una pequeña vista del Inspector de memoria en acción para la depuración nativa de C++ en la Web:
Conclusión
En este artículo, se presentó el Inspector de memoria y se mostró un adelanto de su diseño. Esperamos que el Inspector de memoria te ayude a comprender qué sucede en tu ArrayBuffer :-). Si tienes sugerencias para mejorarlo, informa un error y comunícate con nosotros.
Descarga los canales de vista previa
Considera usar Chrome Canary, Dev o Beta como tu navegador de desarrollo predeterminado. Estos canales de vista previa te brindan acceso a las funciones más recientes de DevTools, te permiten probar las APIs de plataformas web de vanguardia y te ayudan a encontrar problemas en tu sitio antes de que lo hagan tus usuarios.
Comunícate con el equipo de Herramientas para desarrolladores de Chrome
Usa las siguientes opciones para hablar sobre las funciones nuevas, las actualizaciones o cualquier otro tema relacionado con DevTools.
- Envíanos tus comentarios y solicitudes de funciones a crbug.com.
- Informa un problema de DevTools con Más opciones > Ayuda > Informar un problema de DevTools en DevTools.
- Twittea a @ChromeDevTools.
- Deja comentarios en los videos de YouTube sobre las novedades de DevTools o en los videos de YouTube sobre sugerencias de DevTools.