1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/openharmony-developtools_profiler

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
Внести вклад в разработку кода
Синхронизировать код
Отмена
Подсказка: Поскольку Git не поддерживает пустые директории, создание директории приведёт к созданию пустого файла .keep.
Loading...
README_zh.md

Компонент для оптимизации производительности

Обзор

Компонент для оптимизации производительности включает системный и прикладной фреймворк для оптимизации, предназначенный для предоставления разработчикам платформы для анализа проблем с памятью и производительностью.Этот компонент состоит из двух частей: ПК и устройства. Часть для ПК в конечном итоге выпускается как плагин для 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>

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

  1. Создайте файл с определением данных proto _plugin_data.proto, который определяет формат источника данных; формат источника данных указывает, какие данные будут отправлены плагином:

    message PluginData {
        int32 pid = 1;
        string name = 2;
        uint64 count1 = 3;
        uint64 count2 = 4;
        uint64 count3 = 5;
        ......
    }
  2. Создайте конфигурационный файл источника данных 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;
        ......
    }
  3. Определите PluginModuleCallbacks для реализации интерфейса обратного вызова плагина; определите глобальную переменную типа PluginModuleStruct g_pluginModule и зарегистрируйте информацию о плагине.

    static PluginModuleCallbacks callbacks = {
        PluginSessionStart,
        PluginReportResult,
        PluginSessionStop,
    };
    PluginModuleStruct g_pluginModule = {&callbacks, "test-plugin", MAX_BUFFER_SIZE};
  4. Реализуйте метод PluginSessionStart (вы можете использовать своё имя) для реализации интерфейса обратного вызова onPluginSessionStart, который управляет процессом запуска плагина. ```plaintext int PluginSessionStart(const uint8_t* configData, uint32_t configSize) { ...... return 0; }

  5. Реализуйте метод PluginReportResult (вы можете использовать своё имя) для реализации интерфейса обратного вызова onPluginReportResult, который используется для отправки внутренних данных сбора через этот интерфейс:

    int PluginReportResult(uint8_t* bufferData, uint32_t bufferSize)
    {
        ......
        return 0;
    } 
  6. Реализуйте метод 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",
  ]
}
  1. Создание скрипта GN для сборки плагина:```diff +ohos_shared_library("***плагин") {
  • output_name = "***плагин"
  • sources = [
  • "src/***плагин.cpp", // Исходный файл в плагине
  • ]
  • include_dirs = [
  • "../api/include",
  • "${OHOS_PROFILER_DIR}/device/base/include",
  • ]
  • deps = [
  • "${OHOS_PROFILER_3RDPARTY_PROTOBUF_DIR}:protobuf_lite",
  • "${OHOS_PROFILER_3RDPARTY_PROTOBUF_DIR}:protoc_lib",
  • "${OHOS_PROFILER_DIR}/protos/types/plugins/**:plug_cpp", // plug_cpp, сгенерированное выше в ohos_source_set
  • ]
  • install_enable = true
  • subsystem_name = "${OHOS_PROFILER_SUBSYS_NAME}" +}

### Валидация отладки:<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_cmd

Пример сценария использования для сбора информации о памяти

Информация о памяти ядра Используйте следующую команду:
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
    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
Отслеживание использования памяти процессами Если конфигурация захвата имени процесса — com.ohos.mms:
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 не затрагивается).

Пример сценария bytrace/hitrace

Запустите следующую команду:

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

developtools_hdc

developtools_bytrace

Комментарии ( 0 )

Вы можете оставить комментарий после Вход в систему

Введение

Профилировщик производительности, который предоставляет инструмент аналитики для памяти, плагин bytrace и IDE, а также возможности плагинов. Развернуть Свернуть
Apache-2.0
Отмена

Обновления

Пока нет обновлений

Участники

все

Недавние действия

Загрузить больше
Больше нет результатов для загрузки
1
https://api.gitlife.ru/oschina-mirror/openharmony-developtools_profiler.git
git@api.gitlife.ru:oschina-mirror/openharmony-developtools_profiler.git
oschina-mirror
openharmony-developtools_profiler
openharmony-developtools_profiler
master