簡介
性能調優組件包含系統和應用調優框架,旨在為開發者提供一套性能調優平臺,可以用來分析內存、性能等問題。
該組件整體分為PC端和設備端兩部分,PC端最終作為deveco studio的插件進行發布,內部主要包括分為UI繪制、設備管理、進程管理、插件管理、數據導入、數據存儲、 數據分析、Session管理、配置管理等模塊;設備端主要包括命令行工具、服務進程、插件集合、應用程序組件等模塊。設備端提供了插件擴展能力,對外提供了插件接口,基于該擴展能力可以按需定義自己的能力,并集成到框架中來,目前基于插件能力已經完成了實時內存插件,trace插件。下文會重點對設備端提供的插件能力進行介紹。
架構圖
說明
下面針對設備端對外提供的插件擴展能力進行接口和使用說明。
接口說明
下面是設備端插件模塊對外提供的接口:
- PluginModuleCallbacks為插件模塊對外提供的回調接口,插件管理模塊通過該回調接口列表與每一個插件模塊進行交互,每一個新增插件都需要實現該接口列表中的函數。
表 1 PluginModuleCallbacks接口列表
[]()
[]()[]()接口名 | []()[]()類型 | []()[]()描述 |
---|---|---|
[]()[]()PluginModuleCallbacks::onPluginSessionStart | []()[]()int (PluginSessionStartCallback)(const uint8_tconfigData, uint32_t configSize); | []()[]()- 功能: |
[]()[]()插件會話開始接口,開始插件會話時會被調用,用來下發插件配置
- 輸入參數:
[]()[]()configData:配置信息內存塊起始地址
[]()[]()configSize:配置信息內存塊字節數 - 返回值:
[]()[]()0:成功
[]()[]()-1:失敗 |
| []()[]()PluginModuleCallbacks::onPluginReportResult | []()[]()int (PluginReportResultCallback)(uint8_t bufferData, uint32_t bufferSize); | []()[]()- 功能:
[]()[]()插件結果上報接口類型,當任務下發后,框架采集任務會周期性調用此接口請求回填數據 - 輸入參數:
[]()[]()bufferData: 存放結果的內存緩沖區起始地址
[]()[]()bufferSize: 存放結果的內存緩沖區的字節數 - 返回值:
[]()[]()大于0:已經填充的內存字節數
[]()[]()等于0:沒有填充任何內容
[]()[]()小于0:失敗 |
| []()[]()PluginModuleCallbacks::onPluginSessionStop | []()[]()int (*PluginSessionStopCallback)(); | []()[]()- 功能:
[]()[]()采集會話結束接口 - 返回值:
[]()[]()0:成功
[]()[]()-1:失敗 |
| []()[]()PluginModuleCallbacks::onRegisterWriterStruct | []()[]()int (RegisterWriterStructCallback)(WriterStruct writer); | []()[]()- 功能:
[]()[]()采集框架注冊寫數據接口,當插件管理模塊向插件注冊此接口,插件可以主動調用write句柄,進行寫入數據 - 輸入參數:
[]()[]()writer 寫者指針 - 返回值:
[]()[]()0:成功
[]()[]()-1:失敗 | - WriterStruct是上面onRegisterWriterStruct接口中的參數,主要實現寫數據接口,將插件中采集的數據通過該接口進行寫入。
表 2 WriterStruct接口列表
[]()
[]()[]()接口名 | []()[]()類型 | []()[]()描述 |
---|---|---|
[]()[]()WriterStruct::write | []()[]()long (WriteFuncPtr)(WriterStructwriter, const void* data, size_t size); | []()[]()- 功能: |
[]()[]()寫接口,將插件中采集的數據通過writer進行寫入
- 輸入參數:
[]()[]()writer:寫者指針
[]()[]()data:數據緩沖區首字節指針
[]()[]()size: 數據緩沖區的字節數 - 返回值:
[]()[]()0:成功
[]()[]()-1:失敗 |
| []()[]()WriterStruct::flush | []()[]()bool (FlushFuncPtr)(WriterStruct writer); | []()[]()- 功能:
[]()[]()觸發數據上傳接口 - 輸入參數:
[]()[]()writer:寫者指針 - 返回值:
[]()[]()true:成功
[]()[]()false:失敗 | - 下面是插件模塊對外提供的總入口,主要包括表1中的插件模塊回調函數以及插件名稱、插件模塊需要申請的內存大小。
表 3 PluginModuleStruct接口列表
[]()
[]()[]()接口名 | []()[]()類型 | []()[]()描述 |
---|---|---|
[]()[]()PluginModuleStruct::callbacks | []()[]()PluginModuleCallbacks* | []()[]()功能:定義插件回調函數列表 |
[]()[]()PluginModuleStruct::name | []()[]()C style string | []()[]()功能:定義插件名稱 |
[]()[]()PluginModuleStruct::resultBufferSizeHint | []()[]()uint32_t | []()[]()功能:用于提示插件管理模塊調用數據上報接口時使用的內存緩沖區字節數 |
使用說明
下面介紹在設備端基于性能調優框架提供的插件能力,新增一個插件涉及到的關鍵開發步驟:
- 編寫proto數據定義文件_plugin_data.proto_,定義數據源格式,數據源格式決定了插件上報哪些數據:
message PluginData { int32 pid = 1; string name = 2; uint64 count1 = 3; uint64 count2 = 4; uint64 count3 = 5; ...... }
- 編寫數據源配置文件_plugin_config.proto_,采集的行為可以根據配置進行變化,可以設置數據源上報間隔等信息:
message PluginConfig { int32 pid = 1; bool report_interval = 2; int report_counter_id_1 = 3; int report_counter_id_2 = 4; ...... }
- 定義PluginModuleCallbacks實現插件回調接口;定義PluginModuleStruct類型的g_pluginModule全局變量,注冊插件信息。
static PluginModuleCallbacks callbacks = { PluginSessionStart, PluginReportResult, PluginSessionStop, }; PluginModuleStruct g_pluginModule = {&callbacks, "test-plugin", MAX_BUFFER_SIZE};
- 通過PluginSessionStart(名字可以自己定義)實現插件回調接口列表的onPluginSessionStart接口,主要處理插件的開始流程。
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; }
- 編寫proto gn構建腳本, 生成protobuf源文件,protobuf源文件編譯生成目標文件:
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_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", ] }
- 編寫插件GN構建腳本:
ohos_shared_library("***plugin") { output_name = "***plugin" sources = [ "src/***plugin.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", //上面ohos_source_set中生成的plug_cpp ] install_enable = true subsystem_name = "${OHOS_PROFILER_SUBSYS_NAME}" }
調測驗證:
插件動態庫生成后,可以自己編寫測試代碼,通過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"); //獲取開發步驟3中定義的g_pluginModule全局變量
//check memplugin- >callbacks // 通過該指針調用上面開發步驟3中定義的回調函數
return 0;
hiprofiler_cmd 使用說明
參數說明
執行hiprofiler_cmd 為調優業務的離線命令行抓取工具,具體使用方法及命令行參數介紹如下。
可以使用-h
或者--help
參數查看命令的使用描述信息:
hiprofiler_cmd -h
help :
--getport -q : get grpc address
--time -t : trace time
--out -o : output file name
--help -h : make some help
--list -l : plugin list
--start -s : start dependent process
--kill -k : kill dependent process
--config -c : start trace by config file
其余參數使用說明如下:
-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
<
命令參數說明:
- request_id:本次請求的id
- pages:存儲trace數據的buffer大小(4 * pages kb)
- result_file:結果輸出的文件路徑,與-o參數對應
- sample_duration:抓取時長(ms),與-t參數對應
ftrace抓取場景示例
hiprofiler_cmd
-c -
-o /data/local/tmp/hiprofiler_data.htrace
-t 50
-s
-k
<
命令參數說明:
- sample_interval:輪循模式下,插件上報數據的間隔時間(ms)
- trace_period_ms:ftrace插件讀取內核緩沖區數據的間隔時間(ms)
- hitrace_time:hitrace命令行抓取時間,與hiprofiler_cmd下發的-t配置聯動
內存信息抓取場景示例
內核內存信息
使用如下命令:
hiprofiler_cmd
-c -
-o /data/local/tmp/hiprofiler_data.htrace
-t 50
-s
-k
<
虛擬內存統計
使用如下命令:
hiprofiler_cmd
-c -
-o /data/local/tmp/hiprofiler_data.htrace
-t 50
-s
-k
<
進程內存使用跟蹤
如配置抓取的進程名是com.ohos.mms
hiprofiler_cmd
-c -
-o /data/local/tmp/hiprofiler_data.htrace
-t 50
-s
-k
<
配置參數說明:
- pid/process_name:設置抓取的進程ID或者進程名
- max_stack_depth:抓取的棧的深度
- smb_pages:native_daemon和native_hook進程之間存儲數據的共享內存大小(4KB的倍數)
- filter_size:只抓取大于該size的malloc數據(free不受影響)
bytrace/hitrace場景示例
運行如下命令:
hiprofiler_cmd
-c -
-o /data/local/tmp/hiprofiler_data.htrace
-t 30
-s
<
hiperf場景示例
運行如下命令:
hiprofiler_cmd
-c -
-o /data/local/tmp/hiprofiler_data.htrace
-t 50
-s
-k
<
審核編輯 黃宇
-
存儲
+關注
關注
13文章
4347瀏覽量
86059 -
內存
+關注
關注
8文章
3048瀏覽量
74209 -
鴻蒙
+關注
關注
57文章
2390瀏覽量
42968
發布評論請先 登錄
相關推薦
評論