應用可靠性與效能不給力?HarmonyOS HiViewDFX瞭解一下

HarmonyOS開發者社群發表於2023-02-03

作為基礎軟體服務子系統的HarmonyOS HiViewDFX(以下簡稱HiViewDFX)框架,是HarmonyOS的公共基礎設施。包括日誌、事件、跟蹤、故障管理及觀測剖析五大部分,同時也提供了故障檢測、定位和效能觀測剖析的開發套件,以及將端側資料直接對接雲側大資料質量分析平臺和IDE(Integrated Development Environment, 整合開發環境)除錯調優工具。為應對應用開發難題,HiViewDFX提供了高保障能力。

undefined

HarmonyOS HiViewDFX框架圖

一、HiViewDFX介紹

一般地,捕獲異常訊號需要自行增加捕獲異常的機制,透過訊號來感知異常及採集對應的異常日誌,但是往往這類資訊無法有效的與系統資訊關聯。

HiViewDFX為應用開發者提供了具有輕量級故障檢測、精準的故障定位日誌以及快速恢復功能的開發套件,能夠迅速提高應用的可靠性。

如下圖所示,在HarmonyOS系統中首先內建崩潰、洩漏、卡死等輕量級故障檢測器,用來記錄應用在系統側的異常狀態。

其次,在應用程式框架內及執行時增加了異常捕獲能力,使得系統和應用能夠分層檢測和記錄異常資訊,透過開放查詢、訂閱、恢復三個API(Application Programming Interface, 應用程式程式設計介面)提供給開發者。

undefined

HarmonyOS應用異常處理框架圖

在應用崩潰和卡死的時候,HiViewDFX提供的精準日誌定位功能能夠詳細地記錄異常發生時的日誌。

HiViewDFX 提供了對應的應用異常日誌查詢介面,將JS_CRASH, CPP_CRASH, APP_FREEZE這三類故障日誌提供給開發者,並且是結構化的日誌資訊,開發者可以從反饋的資訊中快速獲取到故障的相關資訊。

為給使用者提供更佳的體驗,在日誌資訊反饋異常資料的基礎上,HiViewDFX提供了應用快速恢復的框架(如下圖),當系統感知到JS_CRASH, CPP_CRASH, APP_FREEZE, KILL等故障之後,能快速通知應用,應用將之前的狀態進行儲存,而後系統會自動拉起應用,然後恢復到故障前的原介面。

undefined

應用恢復框架圖

二、HIViewDFX相關工具介紹

HiViewDFX的工具入口---Insight,是DevEco Studio中的外掛,擁有眾多系統能力支撐,如圖所示,有除錯聯結器、HiTrace、HiPerf 以及HiProfiler 框架。

HiViewDFX提供的系統能力包含日誌、事件、分散式跟蹤、故障等。

undefined

HiViewDFX除錯調優架構圖

接下來,就讓我們一起了解下HiViewDFX提供的部分工具吧!

1)除錯聯結器

如下圖所示,除錯聯結器是連線上位機和下位機的通道,通常用做嵌入式開發,常用的連線工具,比如,基於串列埠或者網口的Telnet、SSH等。

HarmonyOS面向不同形態的裝置時,這些裝置可能不具備網口或者USB埠,只有一個串列埠,要支援這個,串列埠上需要具備Shell和檔案IO等功能。有了除錯聯結器作為中轉,就可以讓開發者使用的IDE和其他工具指令碼無需面臨硬體的複雜性,更好的關注除錯和調優本身。

undefined

除錯聯結器原理示意圖

2)HiTrace

如下圖所示,HiTrace工具用於追蹤程式軌跡,進行程式效能分析,支援核心FTrace預置埋點和使用者態打點。

在效能分析中,Trace是最常用的方式,可以說Trace就是效能的日誌,把Trace按照模組分門別類,這就是Trace的Tag。例如,Sched是作業系統核心的排程資訊打點;Ability是Ability模組在使用者態的關鍵生命週期打點。

假設定位某應用掉幀的問題,在分析時,開啟Graphic、Ability、Sched等tag點,可以在Insight裡面分析應用在送顯、圖形模組繪製相關的耗時。

undefined

HiTrace工具原理示意圖

3)HiPerf

如下圖所示,HiPerf是為開發者提供的取樣調優分析工具,透過取樣的方式,可以採集CPU PMU、Tracepoints以及程式熱點函式資訊,並且和Insight聯動,提供離線和實時分析的能力。

HiPerf採集定位過程中會遇到一個難點:使用跨程式語言,在程式執行時,可能會存在一些跨語言的呼叫。例如,從JS呼叫NAPI到C++介面等。

因為是抽樣的呼叫棧採集,如果只採集其中一種語言的呼叫棧會導致兩個語言之間的耗時資料無法同步,從而產生衝突,影響效能問題的度量和定位,所以在呼叫棧採集的時候進行縫合。

undefined

HiPerf工具原理示意圖

如下圖所示,這段JS程式碼呼叫了三個記憶體相關的資料獲取介面,均是NAPI實現的NATIVE介面。

在HiPerf中,首先採集NAPI呼叫JS的呼叫棧資訊,當採集到一個C++的呼叫棧時,此時棧頂是函式NativeFunctionCallBack()的NAPI回撥,則這個NATIVE呼叫棧就可以和前一次採集到的JS呼叫棧合併,最終拼接出一個完整的呼叫棧。

undefined

NAPI呼叫中JS-CPP棧縫合示意圖

除了上述系統內建的分析點,開發者也可以透過HiTrace介面增加自定義的效能分析打點。

如下列程式碼所示,HiTraceMeter的介面比較簡單,找到一段流程的開始和結束,加上Trace打點,就能在Insight中看到Start-End的耗時。

// API
declare namespace hiTraceMeter {
    // Async trace
    function startTrace(name: string, taskId: number, exceptedTime?: number): void;
    function finishTrace(name: string, taskId: number): void;
    // Counter trace
    function traceByValue(name: string, count: number): void;
}
//example
onWindowStageCreate(windowStage) {
    ...
    hiTraceMeter.startTrace('getMainWindow');
    windowStage.getMainWindow().then((win) => {
        Appstorage.SetOrCreate(Constants.MAIN_WINDOW, win);
        hiTraceMeter.finishTrace('getMainWindow');
        ...
    });
    ...
}

HiTrace API介紹及開發樣例圖

4)HiProfilerHiProfiler

框架是基於HiViewDFX基礎能力構建的一個外掛集,可以為Insight提供調優資料採集。

該元件整體分為PC端和裝置端兩部分。

PC端最終作為DevEco Studio的外掛進行釋出,內部主要包括分為UI繪製、裝置管理、程式管理、外掛管理、資料匯入、資料儲存、 資料分析、Session管理、配置管理等模組。

裝置端主要包括命令列工具、服務程式、外掛集合、應用程式元件等模組。

裝置端提供了外掛擴充套件能力,對外提供了外掛介面,基於該擴充套件能力可以按需定義自己的能力,並整合到框架中。

undefined

HiProfiler框架

三、如何查詢記憶體資訊

作業系統對記憶體是分級定義的,從實體地址空間到虛擬地址空間,再分為使用者態和核心態。應用記憶體調優分析的時候,還需要分解到虛擬地址、Ark JS的記憶體、NATIVE的記憶體、字型圖示等資源、So的對映、執行緒棧等,這些都屬於記憶體觀測的範圍。

HiViewDFX提供了HiDumper工具,作用是系統資訊查詢,它提供了系統版本、CPU佔用率、記憶體以及Sa資訊,開發者可以使用HiDumper來分析應用的記憶體(如下圖)。開發者分析記憶體比較關注的是Ark JS Heap以及NATIVE Heap、Pss、Dirty這些指標,如果程式有記憶體洩漏或者一般的記憶體膨脹的問題,可以看到這些值會不斷變大。

undefined

HiDumper檢視記憶體資訊示意圖

如果應用要在程式中監控記憶體,可以使用這組HiDebug介面(如下列程式碼所示),前三個介面是NATIVE記憶體分配器的統計資訊,可以獲取NATIVE分配器的總大小、分配大小和可用大小,後三個介面是從系統Smaps獲取的統計資訊,注意這兩個資訊不是一個維度上的,不能做資料的等同,在使用場景上也有差異。

// API
declare namespace hidebug {
    function getNativeHeapSize(): bigint;
    function getNativeHeapAllocatedSize(): bigint;
    function getNativeHeapFreeSize(): bigint;
    function getPss(): bigint;
    function getSharedDirty(): bigint;
    function getPrivateDirty(): bigint;
}

HiDebug介面示意圖

分配器的資訊經常用於統計程式中對Native記憶體的分配情況,不代表這些記憶體實際被使用,這部分記憶體是開發者可以控制且可以進行最佳化的。

而系統Smaps統計資訊,常用於程式感知自身記憶體的實際佔用大小,這個大小經常受到分配器延遲釋放、系統延遲迴收、Copy-on-write、分配器MetaData額外損耗等,造成統計出來的記憶體資訊和分配器控制的記憶體不完全等同,往往不能作為記憶體最佳化的直接依據,而是作為記憶體壓力統計的依據。

四、如何進行記憶體調優分析

我們透過資訊查詢得知了記憶體的大小資訊,那麼如何進行記憶體分析呢?

如下圖所示,右側部分是開發者使用Insight進行分析的樣例。

首先分析泳道圖上的記憶體曲線,得到三類資料,JS、Native和虛擬記憶體,它們採集的分配資訊基本都比較相似。例如,圖中分配資訊部分,名字和呼叫棧,是區分一塊記憶體的重要資訊,地址和大小是一塊記憶體的基本資訊。引用關係可以幫助我們建立記憶體之間的關係樹,幫助我們更快找到記憶體的引入點。分配時間則可以幫助開發者瞭解哪些記憶體會長時間存留,長時間存留的記憶體是需要重點關注的。

undefined

記憶體分析資料採集原理圖

另外,雖然虛擬記憶體在64位上可能不是一個痛點問題,但是在32位程式上經常會導致問題。32位程式的地址空間只有4GB,如果是32位核心,那麼使用者態一般情況只有3GB地址空間,這種情況下開發者需要關注虛擬記憶體的使用情況,HarmonyOS的做法是在Mmap的地方進行Hook,拿到分配的呼叫棧,並且對系統對映的絕大多數匿名頁都進行了命名。因此不論是檔案頁還是匿名頁,在分配資訊中都能看到頁的命名資訊,這對於記憶體分析非常有幫助。

以上就是HiViewDFX提供的可靠性和效能最佳化除錯調優能力的相關介紹了,歡迎廣大開發者使用HiViewDFX框架來開發一個高可靠高效能的應用!

undefined


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70009402/viewspace-2933864/,如需轉載,請註明出處,否則將追究法律責任。

相關文章