Компонент для оптимизации производительности включает системный и прикладной фреймворк для оптимизации, предназначенный для предоставления разработчикам платформы для анализа проблем с памятью и производительностью.Этот компонент состоит из двух частей: ПК и устройства. Часть для ПК в конечном итоге выпускается как плагин для Deveco Studio. Внутри него основные модули включают UI-рендеринг, управление устройствами, управление процессами, управление плагинами, импорт данных, хранение данных, анализ данных, управление сессиями и управление конфигурациями; часть для устройства включает командную строку, служебный процесс, набор плагинов и компоненты приложений. Устройство предоставляет возможность расширения плагинов и внешние интерфейсы плагинов. На основе этой возможности можно определять свои способности по мере необходимости и интегрировать их в фреймворк. В настоящее время на основе возможностей плагинов уже реализованы реальные плагины для отслеживания использования памяти и трассировки. Ниже будет подробно рассмотрено предоставленное устройством расширенное плагинное обеспечение.## Архитектурная схема
При необходимости исправлю только те части, которые требуют перевода согласно правилам:
/developtools/profiler
├── device # Каталог с кодом для устройств
│ ├── base # Каталог с базовым функционалом
│ │ ├── include # Каталог с хедерами для базового функционала
│ │ ├── src # Каталог с исходниками для базового функционала
│ │ └── test # Каталог с тестами для базового функционала
│ ├── cmds # Каталог с кодом командной строки
│ │ ├── include # Каталог с хедерами для командной строки
│ │ ├── src # Каталог с исходниками для командной строки
│ │ └── test # Каталог с тестами для командной строки
│ └── plugins # Каталог с плагинами
│ ├── api # Каталог с интерфейсами для внешних систем
│ │ ├── include # Каталог с хедерами для интерфейсов
│ │ └── src # Каталог с исходниками для интерфейсов
│ ├── memory_plugin # Каталог с модулем плагина памяти
│ │ ├── include # Каталог с хедерами для модуля плагина памяти
│ │ ├── src # Каталог с исходниками для модуля плагина памяти
│ │ └── test # Каталог с тестами для модуля плагина памяти
│ └── trace_plugin # Каталог с модулем плагина трассировки
│ ├── include # Каталог с хедерами для модуля плагина трассировки
│ ├── src # Каталог с исходниками для модуля плагина трассировки
``` │ └── test # Каталог с тестами для модуля плагина трассировки
├── host # Каталог с кодом для хоста
│ └── ohosprofiler # Каталог с кодом для профиля OHOS
│ └── src # Каталог с исходниками для профиля OHOS
├── protos # Каталог с proto файлами проекта
│ └── innerkits # Каталог с внутренними kitами
│ └── builtin # Каталог с встроенными JS модулями
├── trace_analyzer # Каталог с анализатором трассировки
│ ├── include # Каталог с общими заголовочными файлами для анализа трассировки
│ └── src # Директория с исходными файлами модуля bytrace
├── interfaces # Директория с кодом интерфейсов проекта
│ ├── innerkits # Директория с кодом внутренних интерфейсов между модулями
│ └── kits # Директория для хранения внешних интерфейсов```## Описание расширяемости плагинов для устройств <a name="section2165102016359"></a>
Ниже приведено описание интерфейсов и способов использования расширяемости плагинов, предоставляемых устройствами.
### Описание интерфейсов <a name="section558917318367"></a>
Ниже представлены интерфейсы, предоставляемые модулем плагинов устройства:
- PluginModuleCallbacks — это набор обратных вызовов, предоставленных модулем плагинов. Модуль управления плагинами использует этот список обратных вызовов для взаимодействия с каждым модулем плагинов. Каждый новый плагин должен реализовать все функции в этом списке обратных вызовов.
```**Таблица 1** Список интерфейсов PluginModuleCallbacks<a name="table214mcpsimp"></a>
<table>
<thead align="left">
<tr id="row221mcpsimp">
<th class="cellrowborder" valign="top" width="30%" id="mcps1. 2. 4. 1. 1">
<p id="p223mcpsimp"><a name="p223mcpsimp"></a><a name="p223mcpsimp"></a>Интерфейс</p>
</th>
<th class="cellrowborder" valign="top" width="30.020000000000003%" id="mcps1. 2. 4. 1. 2">
<p id="p225mcpsimp"><a name="p225mcpsimp"></a><a name="p225mcpsimp"></a>Тип</p>
</th>
<th class="cellrowborder" valign="top" width="39.98%" id="mcps1. 2. 4. 1. 3">
<p id="p227mcpsimp"><a name="p227mcpsimp"></a><a name="p227mcpsimp"></a>Описание</p>
</th>
</tr>
</thead>
<tbody>
<tr id="row229mcpsimp">
<td class="cellrowborder" valign="top" width="30%" headers="mcps1. 2. 4. 1. 1 ">
<p id="p231mcpsimp"><a name="p231mcpsimp"></a><a name="p231mcpsimp"></a>PluginModuleCallbacks::onPluginSessionStart</p>
</td>
<td class="cellrowborder" valign="top" width="30.020000000000003%" headers="mcps1. 2. 4. 1. 2 ">
<p id="p233mcpsimp"><a name="p233mcpsimp"></a><a name="p233mcpsimp"></a>int (*PluginSessionStartCallback)(const uint8_t* configData, uint32_t configSize);</p>
</td>
<td class="cellrowborder" valign="top" width="39.98%" headers="mcps1. 2. 4. 1. 3 ">
<ul id="ul1467809165112">
<li>Функционал:
<p id="p1208131116548"><a name="p1208131116548"></a><a name="p1208131116548"></a>Интерфейс начала сессии плагина, вызывается при начале сессии плагина для передачи конфигурации плагина.</p>
</li>
<li>Параметры ввода:
<p id="p104087130518"><a name="p104087130518"></a><a name="p104087130518"></a>configData: начальный адрес блока памяти с конфигурацией</p>
<p id="p32731219115114"><a name="p32731219115114"></a><a name="p32731219115114"></a>configSize: размер блока памяти с конфигурацией в байтах</p>
</li>
<li>Значение возврата:
<p id="p4892128135110"><a name="p4892128135110"></a><a name="p4892128135110"></a>0: успех</p>
<p id="p1621513010517"><a name="p1621513010517"></a><a name="p1621513010517"></a>-1: неудача</p>
</li>
</ul>
</td>
</tr>
</tbody>
</table><p id="p238mcpsimp"><a name="p238mcpsimp"></a><a name="p238mcpsimp"></a>PluginModuleCallbacks::onPluginReportResult</p>
</td>
<td class="cellrowborder" valign="top" width="30.020000000000003%" headers="mcps1.2.4.1.2">
<p id="p240mcpsimp"><a name="p240mcpsimp"></a><a name="p240mcpsimp"></a>int (*PluginReportResultCallback)(uint8_t* bufferData, uint32_t bufferSize);</p>
</td>
<td class="cellrowborder" valign="top" width="39.98%" headers="mcps1.2.4.1.3">
<ul id="ul1467809165112">
<li>Функционал:
<p id="p1208131116548"><a name="p1208131116548"></a><a name="p1208131116548"></a>Интерфейс отчета о результате работы плагина, используется для отправки данных о выполнении операций плагином.</p>
</li>
<li>Параметры ввода:
<p id="p104087130518"><a name="p104087130518"></a><a name="p104087130518"></a>bufferData: указатель на данные, которые будут отправлены</p>
<p id="p32731219115114"><a name="p32731219115114"></a><a name="p32731219115114"></a>bufferSize: размер данных в байтах</p>
</li>
<li>Значение возврата:
<p id="p4892128135110"><a name="p4892128135110"></a><a name="p4892128135110"></a>0: успех</p>
<p id="p1621513010517"><a name="p1621513010517"></a><a name="p1621513010517"></a>-1: неудача</p>
</li>
</ul>
</td>
</tr>
</tbody>
</table>
```markdown
<tr>
<td class="cellrowborder" valign="top" width="39.98%">
<ul id="ul1046263617524">
<li>Функционал:
<p id="p621321105415">Тип интерфейса отчета плагина, который вызывается циклически после выполнения задачи для заполнения данных обратной связи.</p>
</li>
<li>Параметры ввода:
<p id="p12796339115211">bufferData: начальный адрес памяти буфера для хранения результатов.</p>
<p id="p1163214085219">bufferSize: размер памяти буфера для хранения результатов в байтах.</p>
</li>
<li>Значение возврата:
``` <p id="p114391444135212">Больше нуля: количество уже заполненных байтов памяти.</p>
<p id="p117881419526">Равно нулю: ничего не заполнено.</p>
<p id="p7337174625218">Меньше нуля: ошибка.</p>
</li>
</ul>
</td>
</tr>```markdown
<tr id="row243mcpsimp">
<td class="cellrowborder" valign="top" width="30%">
<p id="p245mcpsimp">PluginModuleCallbacks::onPluginSessionStop</p>
</td>
<td class="cellrowborder" valign="top" width="30.020000000000003%">
<p id="p247mcpsimp">int (*PluginSessionStopCallback)();</p>
</td>
<td class="cellrowborder" valign="top" width="39.98%">
<ul id="ul975785275211">
<li>Функционал:
<p id="p11471347135914">Интерфейс завершения сессии сбора данных.</p>
</li>
<li>Значение возврата:
<p id="p4301105945210">0: Успешно.</p>
<p id="p145541757125214">-1: Ошибка.</p>
</li>
</ul>
</td>
</tr>
<tr id="row250mcpsimp">
<td class="cellrowborder" valign="top" width="30%">
<p id="p252mcpsimp">PluginModuleCallbacks::onRegisterWriterStruct</p>
</td>
<td class="cellrowborder" valign="top" width="30.020000000000003%"></td>
<td class="cellrowborder" valign="top" width="39.98%"></td>
</tr>
Продолжение перевода:
<tr id="row250mcpsimp">
<td class="cellrowborder" valign="top" width="30%">
<p id="p252mcpsimp">PluginModuleCallbacks::onRegisterWriterStruct</p>
</td>
<td class="cellrowborder" valign="top" width="30.020000000000003%"></td>
<td class="cellrowborder" valign="top" width="39.98%"></td>
</tr>
``````markdown
<tr id="row250mcpsimp">
<td class="cellrowborder" valign="top" width="30%">
<p id="p252mcpsimp">PluginModuleCallbacks::onRegisterWriterStruct</p>
</td>
<td class="cellrowborder" valign="top" width="30.020000000000003%">
<p id="p254mcpsimp">void (*RegisterWriterStructCallback)(const WriterStruct *writer);</p>
</td>
<td class="cellrowborder" valign="top" width="39.98%">
<ul id="ul1005785275211">
<li>Функционал:
<p id="p11471347135914">Интерфейс регистрации структуры записи.</p>
</li>
<li>Параметры ввода:
<p id="p11471347135914">writer: Указатель на структуру записи.</p>
</li>
<li>Значение возврата:
<p id="p11471347135914">Нет значений возврата.</p>
</li>
</ul>
</td>
</tr>
<table>
<tbody>
<tr>
<td class="cellrowborder" valign="top" width="60.02%"><p id="p254mcpsimp"><a name="p254mcpsimp"></a><a name="p254mcpsimp"></a>int (*RegisterWriterStructCallback)(WriterStruct* writer);</p>
</td>
<td class="cellrowborder" valign="top" width="39.98%" headers="mcps1.2.4.1.3"><a name="ul11459712105318"></a><a name="ul11459712105318"></a><ul id="ul11459712105318">
<li>Функционал:<p id="p16725350135912"><a name="p16725350135912"></a><a name="p16725350135912"></a>Коллекторный фреймворк регистрирует интерфейс записи данных. Когда модуль управления плагинами регистрирует этот интерфейс в плагине, плагин может активировать вызов обработчика write для записи данных.</p>
</li>
<li>Параметры входа:<p id="p741312324531"><a name="p741312324531"></a><a name="p741312324531"></a>writer — указатель на объект записи.</p>
</li>
<li>Возвращаемое значение:<p id="p1937282325319"><a name="p1937282325319"></a><a name="p1937282325319"></a>0 — успех</p>
<p id="p3613421185314"><a name="p3613421185314"></a><a name="p3613421185314"></a>-1 — неудача</p>
</li>
</ul>
</td>
</tr>
</tbody>
</table>
```</table>
- WriterStruct является параметром в интерфейсе onRegisterWriterStruct, который主要用于实现写数据接口,通过此接口将插件中收集的数据进行 записи.**Таблица 2** Список интерфейсов WriterStruct<a name="table1469161115240"></a>
<table>
<thead align="left">
<tr id="row124691911182413">
<th class="cellrowborder" valign="top" width="30%" id="mcps1. 2. 4. 1. 1"><p id="p14469151118247"><a name="p14469151118247"></a><a name="p14469151118247"></a>Интерфейс</p></th>
<th class="cellrowborder" valign="top" width="30.020000000000003%" id="mcps1. 2. 4. 1. 2"><p id="p114691119249"><a name="p114691119249"></a><a name="p114691119249"></a>Тип</p></th>
<th class="cellrowborder" valign="top" width="39.98%" id="mcps1. 2. 4. 1. 3"><p id="p134701611172413"><a name="p134701611172413"></a><a name="p134701611172413"></a>Описание</p></th>
</tr>
</thead>
<tbody>
<tr id="row5470201102420">
<td class="cellrowborder" valign="top" width="30%" headers="mcps1. 2. 4. 1. 1 "><p id="p144702115242"><a name="p144702115242"></a><a name="p144702115242"></a>WriterStruct::write</p></td>
<td class="cellrowborder" valign="top" width="30.020000000000003%" headers="mcps1. 2. 4. 1. 2 "><p id="p347010119246"><a name="p347010119246"></a><a name="p347010119246"></a>long (*WriteFuncPtr)(WriterStruct* writer, const void* data, size_t size);</p></td>
<td class="cellrowborder" valign="top" width="39.98%" headers="mcps1. 2. 4. 1. 3 ">
<ul id="ul1783144245320">
<li>Функционал:<p id="p11675175517597"><a name="p11675175517597"></a><a name="p11675175517597"></a>Интерфейс записи, который позволяет записывать данные, собранные в плагине, через Writer.</p></li>
<li>Параметры входа:<p id="p1812314462537"><a name="p1812314462537"></a><a name="p1812314462537"></a>writer: Указатель на объект Writer.</p>
<p id="p498224618534"><a name="p498224618534"></a><a name="p498224618534"></a>data: Указатель на первый байт данных в буфере.</p>
<p id="p368519478533"><a name="p368519478533"></a><a name="p368519478533"></a>size: Количество байтов в буфере данных.</p></li>
<li>Возвращаемое значение:<p id="p162857527531"><a name="p162857527531"></a><a name="p162857527531"></a>0: Успешно.</p>
<p id="p101121150185318"><a name="p101121150185318"></a><a name="p101121150185318"></a>-1: Несоответствие.</p></li>
</ul>
</td>
</tr>
<tr id="row84706116243"><table>
<tbody>
<tr>
<td class="cellrowborder" valign="top" width="30%" headers="mcps1. 2. 4. 1. 1 ">
<p id="p2047081142415"><a name="p2047081142415"></a><a name="p2047081142415"></a>WriterStruct::flush</p>
</td>
<td class="cellrowborder" valign="top" width="30. 020000000000003%" headers="mcps1. 2. 4. 1. 2 ">void (*FlushFuncPtr)(WriterStruct* writer);
</td>
<td class="cellrowborder" valign="top" width="39. 98%" headers="mcps1. 2. 4. 1. 3 ">
<ul id="ul1783144245320">
<li>Функционал:
<p id="p11675175517597"><a name="p11675175517597"></a><a name="p11675175517597"></a>Интерфейс очистки, который позволяет очистить все незаписанные данные в объекте Writer.</p>
</li>
<li>Параметры входа:
<p id="p1812314462537"><a name="p1812314462537"></a><a name="p1812314462537"></a>writer: Указатель на объект Writer.</p>
</li>
<li>Возвращаемое значение:
<p id="p162857527531"><a name="p162857527531"></a><a name="p162857527531"></a>Нет значений.</p>
</li>
</ul>
</td>
</tr>
<tr>
<td class="cellrowborder" valign="top" width="30%" headers="mcps1. 2. 4. 1. 1 "></td>
<td class="cellrowborder" valign="top" width="30. 020000000000003%" headers="mcps1. 2. 4. 1. 2 ">bool (*FlushFuncPtr)(WriterStruct* writer);
</td>
<td class="cellrowborder" valign="top" width="39. 98%" headers="mcps1. 2. 4. 1. 3 ">
<ul id="ul9562185717538">
<li>Функционал:
<p id="p744185910594"><a name="p744185910594"></a><a name="p744185910594"></a>Вызов интерфейса отправки данных</p>
</li>
<li>Параметры ввода:
<p id="p69601111504"><a name="p69601111504"></a><a name="p69601111504"></a>writer: указатель на объект Writer</p>
</li>
<li>Результат:
<p id="p970375016"><a name="p970375016"></a><a name="p970375016"></a>true: успех</p>
<p id="p1314495407"><a name="p1314495407"></a><a name="p1314495407"></a>false: неудача</p>
</li>
</ul>
</td>
</tr>
</tbody>
</table>
```markdown
- В следующем разделе представлен основной входной метод, предоставляемый плагином, который включает обратные вызовы функций, указанных в таблице 1, а также название плагина и требуемое количество памяти для модуля.
```**Таблица 3** Список интерфейсов PluginModuleStruct<a name="table14418172393018"></a>
<table>
<thead align="left">
<tr id="row14188236300">
<th class="cellrowborder" valign="top" width="30%" id="mcps1. 2. 4. 1. 1"><p id="p041820239304"><a name="p041820239304"></a><a name="p041820239304"></a>Интерфейс</p>
</th>
<th class="cellrowborder" valign="top" width="30. 020000000000003%" id="mcps1. 2. 4. 1. 2"><p id="p34181823153010"><a name="p34181823153010"></a><a name="p34181823153010"></a>Тип</p>
</th>
<th class="cellrowborder" valign="top" width="39. 98%" id="mcps1. 2. 4. 1. 3"><p id="p10418023123011"><a name="p10418023123011"></a><a name="p10418023123011"></a>Описание</p>
</th>
</tr>
</thead>
<tbody>
<tr id="row16418623143016">
<td class="cellrowborder" valign="top" width="30%" headers="mcps1. 2. 4. 1. 1 ">
<p id="p625018817318"><a name="p625018817318"></a><a name="p625018817318"></a>PluginModuleStruct::callbacks</p>
</td>
<td class="cellrowborder" valign="top" width="30. 020000000000003%" headers="mcps1. 2. 4. 1. 2 ">
<p id="p162501689312"><a name="p162501689312"></a><a name="p162501689312"></a>PluginModuleCallbacks*</p>
</td>
<td class="cellrowborder" valign="top" width="39. 98%" headers="mcps1. 2. 4. 1. 3 ">
<p id="p122501085317"><a name="p122501085317"></a><a name="p122501085317"></a>Функционал: определяет список обратных вызовов плагинов</p>
</td>
</tr>
<tr id="row241952313015">
<td class="cellrowborder" valign="top" width="30%" headers="mcps1. 2. 4. 1. 1 ">
<p id="p325018863113"><a name="p325018863113"></a><a name="p325018863113"></a>PluginModuleStruct::name</p>
</td>
<td class="cellrowborder" valign="top" width="30. 020000000000003%" headers="mcps1. 2. 4. 1. 2 ">
<p id="p4250138123112"><a name="p4250138123112"></a><a name="p4250138123112"></a>C-строка</p>
</td>
<td class="cellrowborder" valign="top" width="39. 98%" headers="mcps1. 2. 4. 1. 3 ">
<p id="p425019883115"><a name="p425019883115"></a><a name="p425019883115"></a>Функционал: определяет имя плагина</p>
</td>
</tr>
<tr id="row49481758173013">
<td class="cellrowborder" valign="top" width="30%" headers="mcps1. 2. 4. 1. 1 ">
<p id="p1125010813316"><a name="p1125010813316"></a><a name="p1125010813316"></a>PluginModuleStruct::resultBufferSizeHint</p>
</td>
</tbody>
</table><table>
<tbody>
<tr>
<td class="cellrowborder" valign="top" width="30.02%">
<p id="p142509810319"><a name="p142509810319"></a><a name="p142509810319"></a>uint32_t</p>
</td>
<td class="cellrowborder" valign="top" width="39.98%">
<p id="p1425010813319"><a name="p1425010813319"></a><a name="p1425010813319"></a>Функционал: указывает подсказку размера буфера результата</p>
</td>
</tr>
</tbody>
</table>
```markdown
<table>
<tbody>
<tr>
<td>3 "><p id="p1525112853115"><a name="p1525112853115"></a><a name="p1525112853115"></a>Функция: указывает количество используемых байт в памяти буфера для вызова интерфейса отчета данных плагином управления модулем.</p></td>
</tr>
</tbody>
</table>
Создайте файл с определением данных proto _plugin_data.proto
, который определяет формат источника данных; формат источника данных указывает, какие данные будут отправлены плагином:
message PluginData {
int32 pid = 1;
string name = 2;
uint64 count1 = 3;
uint64 count2 = 4;
uint64 count3 = 5;
......
}
Создайте конфигурационный файл источника данных proto _plugin_config.proto
. Настройки сбора данных могут меняться в зависимости от конфигурации, а также можно установить интервал отправки данных и другую информацию:
message PluginConfig {
int32 pid = 1;
bool report_interval = 2;
int report_counter_id_Yöntem_1 = 3;
int report_counter_id_Yöntem_2 = 4;
......
}
Определите PluginModuleCallbacks
для реализации интерфейса обратного вызова плагина; определите глобальную переменную типа PluginModuleStruct
g_pluginModule
и зарегистрируйте информацию о плагине.
static PluginModuleCallbacks callbacks = {
PluginSessionStart,
PluginReportResult,
PluginSessionStop,
};
PluginModuleStruct g_pluginModule = {&callbacks, "test-plugin", MAX_BUFFER_SIZE};
Реализуйте метод PluginSessionStart
(вы можете использовать своё имя) для реализации интерфейса обратного вызова onPluginSessionStart
, который управляет процессом запуска плагина. ```plaintext
int PluginSessionStart(const uint8_t* configData, uint32_t configSize)
{
......
return 0;
}
Реализуйте метод PluginReportResult
(вы можете использовать своё имя) для реализации интерфейса обратного вызова onPluginReportResult
, который используется для отправки внутренних данных сбора через этот интерфейс:
int PluginReportResult(uint8_t* bufferData, uint32_t bufferSize)
{
......
return 0;
}
Реализуйте метод PluginSessionStop
(вы можете использовать своё имя) для реализации интерфейса обратного вызова onPluginSessionStop
, который управляет процессом завершения работы плагина после его остановки.
int PluginSessionStop()
{
......
return 0;
}
```7. Напишите скрипт GN для компиляции proto, чтобы сгенерировать исходные файлы Protocol Buffers, которые затем компилируются в целевой файл:
action("plugin_cpp_gen") {
script = "${OHOS_PROFILER_DIR}/build/protoc.sh" # зависимости от компилятора
sources = [ # определённые proto-файлы, связанные с плагинами, такие как конфигурационные файлы плагинов и proto-файлы, соответствующие данным плагинов
"plugin_data.proto",
"plugin_config.proto",
]
outputs = [ # результаты, созданные протоколом protoc
"plugin_data.pb.h",
"plugin_data.pb.cc",
"plugin_config.pb.h",
"plugin_config.pb.cc",
]
args = [
"--cpp_out",
"$proto_rel_out_dir",
"--proto_path",
rebase_path(".", root_build_dir),
]
deps = [
"${OHOS_PROFILER_ Yöntem 3RDPARTY_PROTOBUF_DIR}:protoc(${host_toolchain})",
]
}
ohos_source_set("plug_cpp") { # преобразование определённых proto-файлов в cpp-файлы
deps = [
":plugin_cpp_gen",
]
public_deps = [
"${OHOS_PROFILER_3RDPARTY_PROTOBUF_DIR}:protobuf",
"${OHOS_PROFILER_3RDPARTY_PROTOBUF_DIR}:protobuf_lite",
]
include_dirs = [ "$proto_out_dir" ]
sources = [ # исходные файлы, включаемые в цель plug_cpp
"plugin_data.pb.h",
"plugin_data.pb.cc",
"plugin_config.pb.h",
"plugin_config.pb.cc",
]
}
### Валидация отладки:<a name="section35362541215"></a>
После создания динамической библиотеки плагина можно самостоятельно написать тестовый код, который будет использовать `dlopen` для загрузки динамической библиотеки и вызова обратных функций, реализованных в этом коде.
int main(int argc, char** argv) { void* handle; PluginModuleStruct* memplugin; handle = dlopen("./libplugin.z.so", RTLD_LAZY); // Открытие созданной выше динамической библиотеки плагина if (handle == nullptr) { HILOGD("dlopen err:%s.", dlerror()); return 0; } memplugin = (PluginModuleStruct*)dlsym(handle, "g_pluginModule"); // Получение глобальной переменной g_pluginModule, определенной в шаге 3 разработки // проверка memplugin->callbacks // Вызов обратных функций, определенных в шаге 3 разработки через этот указатель return 0; }
## Использование hiprofiler_cmd <a name="section35362541216"></a>
### Описание параметров <a name="section35362541290"></a>
Выполнение команды hiprofiler_cmd является средством для сбора данных для оптимизации бизнес-процессов в режиме офлайн. Дополнительные методы использования и описание параметров командной строки приведены ниже.Для просмотра описаний использования команды можно воспользоваться параметрами `-h` или `--help`:
```sh
hiprofiler_cmd -h
help :
--getport -q : получить адрес grpc
--time -t : время трассировки
--out -o : имя файла вывода
--help -h : помощь
--list -l : список плагинов
--start -s : запустить зависящий процесс
--kill -k : завершить зависящий процесс
--config -c : начать трассировку по конфигурационному файлу
Описание остальных параметров представлено ниже:
-q
или --getport
опция, используется для запроса информации о портах сервиса;-t
или --time
опция, используется для указания времени захвата данных, в секундах;-o
или --out
опция, используется для указания имени файла с выходными данными в офлайн-формате;-h
или --help
опция, используется для вывода справочной информации;-l
или --list
опция, используется для запроса списка плагинов;-s
или --start
опция, используется для запуска зависимых процессов;-k
или --kill
опция, используется для завершения зависимых процессов;-c
или --config
опция, используется для указания конфигурационного файла;hiprofiler_cmd \
-c - \
-o /data/local/tmp/hiprofiler_data.htrace \
-t 50 \
-s \
-k \
<<CONFIG
request_id: 1
session_config {
buffers {
pages: 16384
}
result_file: "/data/local/tmp/hiprofiler_data.htrace"
sample_duration: 50000
}
CONFIG
```Параметры команд:
* `request_id`: ID текущего запроса
* `pages`: размер буфера для хранения данных трассировки (4 * pages КБ)
* `result_file`: путь к выходному файлу с результатами, соответствует параметру `-o`
* `sample_duration`: продолжительность сбора данных (мс), соответствует параметру `-t`
#### Пример сценария использования ftrace <a name="section35362541220"></a>
```sh
hiprofiler_cmd \
-c - \
-o /data/local/tmp/hiprofiler_data.htrace \
-t 50 \
-s \
-k \
<<CONFIG
request_id: 1
session_config {
buffers {
pages: 16384
}
result_file: "/data/local/tmp/hiprofiler_data.htrace"
sample_duration: 50000
}
plugin_configs {
plugin_name: "ftrace-plugin"
sample_interval: 1000
config_data {
ftrace_events: "sched/sched_switch"
ftrace_events: "power/suspend_resume"
ftrace_events: "sched/sched_wakeup"
ftrace_events: "sched/sched_wakeup_new"
ftrace_events: "sched/sched_waking"
ftrace_events: "sched/sched_process_exit"
ftrace_events: "sched/sched_process_free"
ftrace_events: "task/task_newtask"
ftrace_events: "task/task_rename"
buffer_size_kb: 2048
flush_interval_ms: 1000
flush_threshold_kb: 4096
parse_ksyms: true
clock: "mono"
trace_period_ms: 200
debug_on: false
hitrace_time: 50
}
}
CONFIG
Параметры команд:
sample_interval
: интервал времени между отчетами плагина в циклическом режиме (мс)trace_period_ms
: интервал времени между чтением данных из ядра буферов плагина ftrace (мс)hitrace_time
: время выполнения команды hitrace для сбора данных, связано с параметром -t
команды hiprofiler_cmdhiprofiler_cmd \
-c - \
-o /data/local/tmp/hiprofiler_data.htrace \
-t 50 \
-s \
-k \
<<CONFIG
request_id: 1
session_config {
buffers {
pages: 16384
}
result_file: "/data/local/tmp/hiprofiler_data.htrace"
sample_duration: 50000
}
plugin_configs {
plugin_name: "memory-plugin"
sample_interval: 5000
config_data {
report_process_tree: true
report_sysmem_mem_info: true
sys_meminfo_counters: PMEM_ACTIVE
sys_meminfo_counters: PMEM_ACTIVE_ANON
sys_meminfo_counters: PMEM_ACTIVE_FILE
sys_meminfo_counters: PMEM_ANON_PAGES
sys_meminfo_counters: PMEM_BUFFERS
sys_meminfo_counters: PMEM_CACHED
sys_meminfo_counters: PMEM_CMA_FREE
sys_meminfo_counters: PMEM_CMA_TOTAL
sys_meminfo_counters: PMEM_COMMIT_LIMIT
sys_meminfo_counters: PMEM_COMMITED_AS
sys_meminfo_counters: PMEM_DIRTY
sys_meminfo_counters: PMEM_INACTIVE
sys_meminfo_counters: PMEM_INACTIVE_ANON
sys_meminfo_counters: PMEM_INACTIVE_FILE
sys_meminfo_counters: PMEM_KERNEL_STACK
sys_meminfo_counters: PMEM_MAPPED
sys_meminfo_counters: PMEM_MEM_AVAILABLE
sys_meminfo_counters: PMEM_MEM_FREE
sys_meminfo_counters: PMEM_MEM_TOTAL
sys_meminfo_counters: PMEM_MLOCKED
sys_meminfo_counters: PMEM_PAGE_TABLES
sys_meminfo_counters: PMEM_SHMEM
sys_meminfo_counters: PMEM_SLAB
sys_meminfo_counters: PMEM_SLAB_RECLAIMABLE
sys_meminfo_counters: PMEM_SLAB_UNRECLAIMABLE
sys_meminfo_counters: PMEM_SWAP_CACHED
sys_meminfo_counters: PMEM_SWAP_FREE
sys_meminfo_counters: PMEM_SWAP_TOTAL
sys_meminfo_counters: PMEM_UNEVICTABLE
sys_meminfo_counters: PMEM_VMALLOC_CHUNK
sys_meminfo_counters: PMEM_VMALLOC_TOTAL
sys_meminfo_counters: PMEM_VMALLOC_USED
sys_meminfo_counters: PMEM_WRITEBACK
sys_meminfo_counters: PMEM_KERNEL_RECLAIMABLE
report_sysmem_vmem_info: true
report_process_mem_info: true
report_app_mem_info: false
report_app_mem_by_memory_service: false
}
}
CONFIG
hiprofiler_cmd \
-c - \
-o /data/local/tmp/hiprofiler_data.htrace \
-t 50 \
-s \
-k \
<<CONFIG
request_id: 1
session_config {
buffers {
pages: 16384
}
result_file: "/data/local/tmp/hiprofiler_data.htrace"
sample_duration: 50000
}
plugin_configs {
plugin_name: "memory-plugin"
sample_interval: 5000
config_data {
report_process_tree: true
report_sysmem_mem_info: true
report_sysmem_vmem_info: true
sys_vmeminfo_counters: VMEMINFO_UNSPECIFIED
sys_vmeminfo_counters: VMEMINFO_NR_FREE_PAGES
sys_vmeminfo_counters: VMEMINFO_NR_ALLOC_BATCH
sys_vmeminfo_counters: VMEMINFO_NR_INACTIVE_ANON
sys_vmeminfo_counters: VMEMINFO_NR_ACTIVE_ANON
sys_vmeminfo_counters: VMEMINFO_NR_INACTIVE_FILE
sys_vmeminfo_counters: VMEMINFO_NR_ACTIVE_FILE
sys_vmeminfo_counters: VMEMINFO_NR_UNEVICTABLE
sys_vmeminfo_counters: VMEMINFO_NR_MLOCK
sys_vmeminfo_counters: VMEMINFO_NR_ANON_PAGES
sys_vmeminfo_counters: VMEMINFO_NR_MAPPED
sys_vmeminfo_counters: VMEMINFO_NR_FILE_PAGES
sys_vmeminfo_counters: VMEMINFO_NR_DIRTY
sys_vmeminfo_counters: VMEMINFO_NR_WRITEBACK
sys_vmeminfo_counters: VMEMINFO_NR_SLAB_RECLAIMABLE
sys_vmeminfo_counters: VMEMINFO_NR_SLAB_UNRECLAIMABLE
sys_vmeminfo_counters: VMEMINFO_NR_PAGE_TABLE_PAGES
sys_vmeminfo_counters: VMEMINFO_NR_KERNEL_STACK
sys_vmeminfo_counters: VMEMINFO_NR_OVERHEAD
sys_vmeminfo_counters: VMEMINFO_NR_UNSTABLE
sys_vmeminfo_counters: VMEMINFO_NR_BOUNCE
sys_vmeminfo_counters: VMEMINFO_NR_VMSCAN_WRITE
sys_vmeminfo_counters: VMEMINFO_NR_VMSCAN_IMMEDIATE_RECLAIM
sys_vmeminfo_counters: VMEMINFO_NR_WRITEBACK_TEMP
sys_vmeminfo_counters: VMEMINFO_NR_ISOLATED_ANON
sys_vmeminfo_counters: VMEMINFO_NR_ISOLATED_FILE
sys_vmeminfo_counters: VMEMINFO_NR_SHMEM
sys_vmeminfo_counters: VMEMINFO_NR_DROPPED_LRU_NOTTRAVERSE
sys_vmeminfo_counters: VMEMINFO_NR_DIRTIED
sys_vmeminfo_counters: VMEMINFO_NR_WRITTEN
sys_vmeminfo_counters: VMEMINFO_NR_PAGES_SCANNED
sys_vmeminfo_counters: VMEMINFO_WORKINGSET_REFAULT
sys_vmeminfo_counters: VMEMINFO_WORKINGSET_ACTIVATE
sys_vmeminfo_counters: VMEMINFO_WORKINGSET_NODERECLAIM
sys_vmeminfo_counters: VMEMINFO_NR_ANON_TRANSPARENT_HUGEPAGES
sys_vmeminfo_counters: VMEMINFO_NR_FREE_CMA
}
}
``````markdown
sys_vmeminfo_counters: VMEMINFO_NR_SWAPCACHE
sys_vmeminfo_counters: VMEMINFO_NR_DIRTY_THRESHOLD
sys_vmeminfo_counters: VMEMINFO_NR_DIRTY_BACKGROUND_THRESHOLD
sys_vmeminfo_counters: VMEMINFO_PGPGIN
}
{
sys_vmeminfo_counters: VMEMINFO_PGPGOUT
sys_vmeminfo_counters: VMEMINFO_PGPGOUTCLEAN
sys_vmeminfo_counters: VMEMINFO_PSWPIN
sys_vmeminfo_counters: VMEMINFO_PSWPOUT
sys_vmeminfo_counters: VMEMINFO_PGALLOC_DMA
sys_vmeminfo_counters: VMEMINFO_PGALLOC_NORMAL
sys_vmeminfo_counters: VMEMINFO_PGALLOC_MOVABLE
sys_vmeminfo_counters: VMEMINFO_PGFREE
sys_vmeminfo_counters: VMEMINFO_PGACTIVATE
sys_vmeminfo_counters: VMEMINFO_PGDEACTIVATE
sys_vmeminfo_counters: VMEMINFO_PGFAULT
sys_vmeminfo_counters: VMEMINFO_PGMAJFAULT
sys_vmeminfo_counters: VMEMINFO_PGREFILL_DMA
sys_vmeminfo_counters: VMEMINFO_PGREFILL_NORMAL
sys_vmeminfo_counters: VMEMINFO_PGREFILL_MOVABLE
sys_vmeminfo_counters: VMEMINFO_PGSTEAL_KSWAPD_DMA
sys_vmeminfo_counters: VMEMINFO_PGSTEAL_KSWAPD_NORMAL
sys_vmeminfo_counters: VMEMINFO_PGSTEAL_KSWAPD_MOVABLE
sys_vmeminfo_counters: VMEMINFO_PGSTEAL_DIRECT_DMA
sys_vmeminfo_counters: VMEMINFO_PGSTEAL_DIRECT_NORMAL
sys_vmeminfo_counters: VMEMINFO_PGSTEAL_DIRECT_MOVABLE
sys_vmeminfo_counters: VMEMINFO_PGSCAN_KSWAPD_DMA
sys_vmeminfo_counters: VMEMINFO_PGSCAN_KSWAPD_NORMAL
sys_vmeminfo_counters: VMEMINFO_PGSCAN_KSWAPD_MOVABLE
sys_vmeminfo_counters: VMEMINFO_PGSCAN_DIRECT_DMA
sys_vmeminfo_counters: VMEMINFO_PGSCAN_DIRECT_NORMAL
sys_vmeminfo_counters: VMEMINFO_PGSCAN_DIRECT_MOVABLE
sys_vmeminfo_counters: VMEMINFO_PGSCAN_DIRECT_THROTTLE
sys_vmeminfo_counters: VMEMINFO_PGINODESTEAL
sys_vmeminfo_counters: VMEMINFO_SLABS_SCANNED
sys_vmeminfo_counters: VMEMINFO_KSWAPD_INODESTEAL
sys_vmeminfo_counters: VMEMINFO_KSWAPD_LOW_WMARK_HIT_QUICKLY
sys_vmeminfo_counters: VMEMINFO_KSWAPD_HIGH_WMARK_HIT_QUICKLY
sys_vmeminfo_counters: VMEMINFO_PAGEOUTRUN
sys_vmeminfo_counters: VMEMINFO_ALLOCSTALL
sys_vmeminfo_counters: VMEMINFO_PGROTATED
sys_vmeminfo_counters: VMEMINFO_DROP_PAGECACHE
sys_vmeminfo_counters: VMEMINFO_DROP_SLAB
sys_vmeminfo_counters: VMEMINFO_PGMIGRATE_SUCCESS
sys_vmeminfo_counters: VMEMINFO_PGMIGRATE_FAIL
sys_vmeminfo_counters: VMEMINFO_COMPACT_MIGRATE_SCANNED
sys_vmeminfo_counters: VMEMINFO_COMPACT_FREE_SCANNED
``` sys_vmeminfo_counters: VMEMINFO_COMPACT_ISOLATED
sys_vmeminfo_counters: VMEMINFO_COMPACT_STALL
sys_vmeminfo_counters: VMEMINFO_COMPACT_FAIL
sys_vmeminfo_counters: VMEMINFO_COMPACT_SUCCESS
sys_vmeminfo_counters: VMEMINFO_COMPACT_DAEMON_WAKE
sys_vmeminfo_counters: VMEMINFO_UNEVICTABLE_PGS_CULLED
sys_vmeminfo_counters: VMEMINFO_UNEVICTABLE_PGS_SCANNED
sys_vmeminfo_counters: VMEMINFO_UNEVICTABLE_PGS_RESCUED
sys_vmeminfo_counters: VMEMINFO_UNEVICTABLE_PGS_MLOCKED
sys_vmeminfo_counters: VMEMINFO_UNEVICTABLE_PGS_MUNLOCKED
sys_vmeminfo_counters: VMEMINFO_UNEVICTABLE_PGS_CLEARED
sys_vmeminfo_counters: VMEMINFO_UNEVICTABLE_PGS_STRANDED
sys_vmeminfo_counters: VMEMINFO_NR_ZSPAGES
sys_vmeminfo_counters: VMEMINFO_NR_ION_HEAP
sys_vmeminfo_counters: VMEMINFO_NR_GPU_HEAP
sys_vmeminfo_counters: VMEMINFO_ALLOCSTALL_DMA
sys_vmeminfo_counters: VMEMINFO_ALLOCSTALL_MOVABLE
sys_vmeminfo_counters: VMEMINFO_ALLOCSTALL_NORMAL
sys_vmeminfo_counters: VMEMINFO_COMPACT_DAEMON_FREE_SCANNED
sys_vmeminfo_counters: VMEMINFO_COMPACT_DAEMON_MIGRATE_SCANNED
sys_vmeminfo_counters: VMEMINFO_NR_FASTRPC
sys_vmeminfo_counters: VMEMINFO_NR_INDIRECTLY_RECLAIMABLE
sys_vmeminfo_counters: VMEMINFO_NR_ION_HEAP_POOL
sys_vmeminfo_counters: VMEMINFO_NR_KERNEL_MISC_RECLAIMABLE
sys_vmeminfo_counters: VMEMINFO_NR_SHADOW_CALL_STACK_BYTES
sys_vmeminfo_counters: VMEMINFO_NR_SHMEM_HUGEPAGES
sys_vmeminfo_counters: VMEMINFO_NR_SHMEM_PMDMAPPED
sys_vmeminfo_counters: VMEMINFO_NR_UNRECLAIMABLE_PAGES
sys_vmeminfo_counters: VMEMINFO_NR_ZONE_ACTIVE_ANON
sys_vmeminfo_counters: VMEMINFO_NR_ZONE_ACTIVE_FILE
sys_vmeminfo_counters: VMEMINFO_NR_ZONE_INACTIVE_ANON
sys_vmeminfo_counters: VMEMINFO_NR_ZONE_INACTIVE_FILE
sys_vmeminfo_counters: VMEMINFO_NR_ZONE_UNEVICTABLE
sys_vmeminfo_counters: VMEMINFO_NR_ZONE_WRITE_PENDING
sys_vmeminfo_counters: VMEMINFO_OOM_KILL
sys_vmeminfo_counters: VMEMINFO_PGLAZYFREE
sys_vmeminfo_counters: VMEMINFO_PGLAZYFREED
sys_vmeminfo_counters: VMEMINFO_PGREFILL
sys_vmeminfo_counters: VMEMINFO_PGSCAN_DIRECT
sys_vmeminfo_counters: VMEMINFO_PGSCAN_KSWAPD
sys_vmeminfo_counters: VMEMINFO_PGSKIP_DMA
sys_vmeminfo_counters: VMEMINFO_PGSKIP_MOVABLE
sys_vmeminfo_counters: VMEMINFO_PGSKIP_NORMAL
sys_vmeminfo_counters: VMEMINFO_PGSTEAL_DIRECT
sys_vmeminfo_counters: VMEMINFO_PGSTEAL_KSWAPD
sys_vmeminfo_counters: VMEMINFO_SWAP_RA```yaml
sys_vmeminfo_counters: VMEMINFO_SWAP_RA_HIT
sys_vmeminfo_counters: VMEMINFO_WORKINGSET_RESTORE
report_process_mem_info: true
report_app_mem_info: false
report_app_mem_by_memory_service: false
hiprofiler_cmd \
-c - \
-o /data/local/tmp/hiprofiler_data.htrace \
-t 50 \
-s \
-k \
<<CONFIG
request_id: 1
session_config {
buffers {
pages: 16384
}
result_file: "/data/local/tmp/hiprofiler_data.htrace"
sample_duration: 50000
}
plugin_configs {
plugin_name: "nativehook"
sample_interval: 5000
config_data {
save_file: false
filter_size: 4096
smb_pages: 16384
max_stack_depth: 10
process_name: "com.ohos.mms"
malloc_free_matching_interval: 1000
malloc_free_matching_cnt: 1000
string_compressed: true
fp_unwind: true
}
}
CONFIG
Параметры конфигурации:
pid/process_name
: Устанавливает ID или имя захваченного процесса.max_stack_depth
: Глубина захваченного стека.smb_pages
: Размер общего буфера памяти между native_daemon и native_hook (кратно 4 КБ).filter_size
: Только захватывает данные malloc размером больше этого значения (free не затрагивается).Запустите следующую команду:
hiprofiler_cmd \
-c - \
-o /data/local/tmp/hiprofiler_data.htrace \
-t 30 \
-s \
<<CONFIG
request_id: 1
session_config {
buffers {
pages: 1000
}
result_file: "/data/local/tmp/hiprofiler_data.htrace"
sample_duration: 30000
}
plugin_configs {
plugin_name: "ftrace-plugin"
sample_interval: 1000
config_data {
hitrace_time: 10
hitrace_categories: "ability"
hitrace_categories: "ace"
hitrace_categories: "binder"
hitrace_categories: "dsoftbus"
hitrace_categories: "freq"
hitrace_categories: "graphic"
hitrace_categories: "idle"
hitrace_categories: "memory"
hitrace_categories: "dcamera"
hitrace_categories: "ohos"
hitrace_categories: "rpc"
hitrace_categories: "sched"
hitrace_categories: "sync"
hitrace_categories: "window"
buffer_size_kb: 51200
flush_interval_ms: 1000
flush_threshold_kb: 4096
parse_ksyms: true
clock: "mono"
trace_period_ms: 200
debug_on: false
}
}
CONFIG
```#### Пример сценария hiperf <a name="section35362541226"></a>
Запустите следующую команду:
```sh
hiprofiler_cmd \
-c - \
-o /data/local/tmp/hiprofiler_data.htrace \
-t 50 \
-s \
-k \
<<CONFIG
request_id: 1
session_config {
buffers {
pages: 16384
}
result_file: "/data/local/tmp/hiprofiler_data.htrace"
sample_duration: 50000
}
plugin_configs {
plugin_name: "hiperf-plugin"
sample_interval: 5000
config_data {
is_root: false
outfile_name: "/data/local/tmp/perf.data"
record_args: "-f 1000 -a --cpu-limit 100 -e hw-cpu-cycles,sched:sched_waking --call-stack dwarf --clockid monotonic --offcpu -m 256"
}
}
CONFIG
developtools_profiler
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Комментарии ( 0 )