Знакомство с инспектором памяти

Ким-Ань Тран
Kim-Anh Tran

В этой статье представлен инспектор памяти, который появился в Chrome 91. Он позволяет вам проверять память ArrayBuffer, TypedArray, DataView и Wasm.

Введение

Вам когда-нибудь хотелось разобраться в данных в вашем ArrayBuffer? До появления Memory Inspector DevTools позволял лишь ограниченное представление о ArrayBuffers. Проверка из представления «Область» во время сеанса отладки ограничивалась просмотром списка отдельных значений в буфере массива, что затрудняло понимание данных в целом. В качестве примера, представление «Область» показывает буфер как расширяемые диапазоны массивов в примере ниже:

Представление области действия в DevTools

Переход к определенному диапазону в буфере был болезненной проблемой, требующей от пользователя прокрутки вниз, чтобы наконец добраться до этого индекса. Но даже если переход к нужной позиции будет простым, этот способ фактической проверки значений является громоздким: трудно сказать, что означают эти числа. В частности, что, если их следует интерпретировать не как отдельные байты, а, например, как 32-битные целые числа?

Проверка значений с помощью инспектора памяти

Инспектор памяти

В Chrome 91 мы представляем инспектор памяти — инструмент для проверки буферов массивов. Возможно, вы ранее видели инструменты проверки памяти для просмотра двоичных данных, которые отображают двоичное содержимое в сетке вместе с их адресами и предлагают различные способы интерпретации основных значений. Вот что вам предлагает инспектор памяти. С помощью инспектора памяти теперь вы можете просматривать содержимое, перемещаться по нему и выбирать типы, которые будут использоваться для интерпретации имеющихся значений. Он показывает значения ASCII непосредственно рядом с байтами и позволяет пользователю выбирать другой порядок байтов. Посмотрите, как работает инспектор памяти ниже:

Хотите попробовать? Чтобы узнать, как открыть инспектор памяти и просмотреть буфер массива (или TypedArray, DataView или Wasm Memory), а также дополнительную информацию о том, как его использовать, перейдите к нашей документации по инспектору памяти . Попробуйте эти игрушечные примеры (для JS, Wasm и C++).

Проектирование инспектора памяти

В этой части мы рассмотрим, как инспектор памяти спроектирован с использованием веб-компонентов, и покажем одну из поставленных перед нами целей проектирования и то, как мы ее реализовали. Если вам интересно и вы хотите узнать больше, ознакомьтесь с нашей проектной документацией для инспектора памяти.

Возможно, вы видели публикацию в нашем блоге «Миграция на веб-компоненты» , где Джек опубликовал наше внутреннее руководство о том, как создавать компоненты пользовательского интерфейса с помощью веб-компонентов. Переход на веб-компоненты совпал с нашей работой над инспектором памяти, и в результате мы решили попробовать новую систему. Ниже представлена ​​диаграмма, показывающая компоненты, которые мы создали для создания инспектора памяти (обратите внимание, что внутри компании мы называем его «Инспектор линейной памяти» ):

Веб-компоненты

Компонент LinearMemoryInspector — это родительский компонент, который объединяет подкомпоненты, составляющие все элементы в инспекторе памяти. По сути, он принимает Uint8Array и address , и при каждом изменении любого из них он передает данные своим дочерним элементам, что запускает повторный рендеринг. Сам LinearMemoryInspector отображает три подкомпонента:

  1. LinearMemoryViewer (показывает значения),
  2. LinearMemoryNavigator (позволяющий навигацию) и
  3. LinearMemoryValueInterpreter (показывает различные интерпретации типов базовых данных).

Последний сам по себе является родительским компонентом, который отображает ValueInterpreterDisplay (показывает значения) и ValueInterpreterSettings (выбирает, какие типы отображать на дисплее).

Каждый из компонентов предназначен для представления только одного небольшого компонента пользовательского интерфейса, поэтому при необходимости компоненты можно использовать повторно. Всякий раз, когда в компоненте устанавливаются новые данные, запускается повторная отрисовка, которая показывает отраженные изменения в данных, установленных в компоненте. Ниже показан один из примеров рабочего процесса с нашими компонентами, где пользователь меняет адрес в адресной строке, что запускает обновление путем установки новых данных, в данном случае адреса для просмотра:

Схема компонентов

LinearMemoryInspector добавляет себя в качестве прослушивателя LinearMemoryNavigator . Функция addressChanged должна запускаться при событии address-changed . Как только пользователь теперь редактирует ввод адреса, отправляется вышеупомянутое событие, так что вызывается функция addressChanged . Эта функция теперь сохраняет адрес внутри себя и обновляет свои подкомпоненты с помощью установщика data(address, ..) . Субкомпоненты сохраняют адрес внутри себя и повторно отображают свои представления, показывая контент по этому конкретному адресу.

Цель разработки: сделать производительность и потребление памяти независимыми от размера буфера.

При разработке инспектора памяти мы учитывали один аспект: производительность инспектора памяти не должна зависеть от размера буфера.

Как вы видели в предыдущей части, компонент LinearMemoryInspector принимает UInt8Array для визуализации значений. В то же время мы хотели убедиться, что инспектору памяти не нужно будет хранить все данные, поскольку инспектор памяти показывает только их часть (например, объем памяти Wasm может достигать 4 ГБ, и мы не хотим для хранения 4 ГБ в инспекторе памяти).

Поэтому, чтобы гарантировать, что скорость и потребление памяти инспектором памяти не зависят от фактического буфера, который мы показываем, мы позволяем компоненту LinearMemoryInspector сохранять только поддиапазон исходного буфера.

Чтобы это работало, LinearMemoryInspector сначала должен принять еще два аргумента: memoryOffset и outerMemoryLength . memoryOffset указывает смещение, с которого начинается переданный Uint8Array , и требуется для отображения правильных адресов данных. outerMemoryLength — это длина исходного буфера, она необходима, чтобы понять, какой диапазон мы можем показать:

буфер

С помощью этой информации мы можем быть уверены, что сможем отображать то же представление, что и раньше (содержимое вокруг address ), фактически не имея всех данных на месте. Так что же делать, если запрошен другой адрес, попадающий в другой диапазон? В этом случае LinearMemoryInspector запускает RequestMemoryEvent , который обновляет текущий сохраняемый диапазон; пример показан ниже:

Блок-схема триггера событий

В этом примере пользователь перемещается по странице памяти (инспектор памяти использует подкачку для отображения фрагментов данных), что вызывает событие PageNavigationEvent , которое в свою очередь запускает RequestMemoryEvent . Это событие запускает выборку нового диапазона, который затем передается компоненту LinearMemoryInspector посредством установки данных. В результате мы показываем вновь полученные данные.

О, а ты знал? Вы даже можете проверять память в коде Wasm и C/C++.

Инспектор памяти доступен не только для ArrayBuffers в JavaScript, но также может использоваться для проверки памяти Wasm и памяти, на которую указывают ссылки/указатели C/C++ (с использованием нашего расширения DWARF — попробуйте, если вы еще этого не сделали! См . «Отладка WebAssembly с помощью современных инструментов» здесь . Небольшой обзор использования инспектора памяти для встроенной отладки C++ в Интернете:

Проверка памяти в C++

Заключение

В этой статье был представлен инспектор памяти и кратко показан его дизайн. Мы надеемся, что инспектор памяти поможет вам понять, что происходит в вашем ArrayBuffer :-). Если у вас есть предложения по улучшению, дайте нам знать и сообщите об ошибке !

Загрузите предварительный просмотр каналов

Рассмотрите возможность использования Chrome Canary , Dev или Beta в качестве браузера для разработки по умолчанию. Эти каналы предварительного просмотра предоставляют вам доступ к новейшим функциям DevTools, позволяют тестировать передовые API-интерфейсы веб-платформы и помогают находить проблемы на вашем сайте раньше, чем это сделают ваши пользователи!

Свяжитесь с командой Chrome DevTools

Используйте следующие параметры, чтобы обсудить новые функции, обновления или что-либо еще, связанное с DevTools.