0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

【鴻蒙】webview內(nèi)存泄漏問題的分析報(bào)告

王程 ? 2024-03-02 15:12 ? 次閱讀

1 關(guān)鍵字

webview;內(nèi)存泄漏

2 問題描述

問題現(xiàn)象:在 3.1release 版本和 3.2bete1 版本中,在 RK3568 上使用 etsWeb 和其他瀏覽器時(shí),webview 所占的內(nèi)存會(huì)隨著使用而不斷增大,最終導(dǎo)致瀏覽器 APP 因內(nèi)存泄漏而崩潰。

3 問題原因

3.1 正常機(jī)制

在任意版本上使用瀏覽器 APP,可以長(zhǎng)時(shí)間正常瀏覽網(wǎng)頁(yè)。

3.2 異常機(jī)制

在 3.1release 和 3.2beta1 上使用瀏覽器 APP,長(zhǎng)時(shí)間瀏覽網(wǎng)頁(yè)后,應(yīng)用會(huì)崩潰。

4 解決方案

  • arkui web 側(cè),在析構(gòu)函數(shù)中調(diào)用 OnDestroy 方法銷毀組件
    //文件路徑
foundationarkuiace_engineframeworkscorecomponentswebresourceweb_delegate.cpp
WebDelegate::~WebDelegate()
{
    ReleasePlatformResource();
    if (nweb_) {
        nweb_->OnDestroy();
    }
}

?

  • web 內(nèi)核中的 compositor 被 delete 的過程如下
//文件路徑srcceflibcefbrowserosrrender_widget_host_view_osr.cc
#include "ui/gfx/geometry/size_conversions.h"
#include "ui/touch_selection/touch_selection_controller.h"
 
// static
std::unordered_map
    CefRenderWidgetHostViewOSR::compositor_map_;
 
std::unordered_map CefRenderWidgetHostViewOSR::accelerate_widget_map_;
 
namespace {
// The maximum number of damage rects to cache for outstanding frame requests
// (for OnAcceleratedPaint).
const size_t kMaxDamageRects = 10;
  compositor_->SetRootLayer(root_layer_.get());
  compositor_->AddChildFrameSink(GetFrameSinkId());
#else
  LOG(INFO) (browser_impl_->GetAcceleratedWidget());
  ui::Compositor* compositor = CefRenderWidgetHostViewOSR::GetCompositor(
      browser_impl_->GetAcceleratedWidget());
  accelerate_widget_map_[browser_impl_->GetAcceleratedWidget()]++;
  if (!compositor) {
    compositor = new ui::Compositor(
        context_factory->AllocateFrameSinkId(), context_factory,
  if (!compositor_) {
    return;  // already released
  }
#else
  if (!browser_impl_) {
    return;
  }
  auto it = accelerate_widget_map_.find(browser_impl_->GetAcceleratedWidget());
  if (it == accelerate_widget_map_.end()) {
    return;
  }
#endif
  // Marking the DelegatedFrameHost as removed from the window hierarchy is
  // necessary to remove all connections to its old ui::Compositor.
 
  if (delegated_frame_host_) {
    if (is_showing_) {
      delegated_frame_host_->WasHidden(content::DelegatedFrameHost::HiddenCause::kOther);
    }
    delegated_frame_host_->DetachFromCompositor();
    delegated_frame_host_.reset(nullptr);
  }
 
#ifdef DISABLE_GPU
  compositor_.reset(nullptr);
#else
  LOG(INFO) GetAcceleratedWidget()] == 0) {
    if (!browser_impl_) {
      return;
    }
    LOG(INFO) (browser_impl_->GetAcceleratedWidget());
    auto it = compositor_map_.find(browser_impl_->GetAcceleratedWidget());
    if (it != compositor_map_.end()) {
      if (it->second != nullptr) {
        delete it->second;
      }
      compositor_map_.erase(it);
    }
    accelerate_widget_map_.erase(browser_impl_->GetAcceleratedWidget());
  }
#endif
}

?

5 定位過程

在 RK3568 上使用 etsWeb 時(shí),使用下列命令可以看到瀏覽器的進(jìn)程號(hào) pid 和進(jìn)程所占內(nèi)存情況。

ps -ef #查看pid
hidumper --mem 1021 #查看進(jìn)程所占內(nèi)存,這里的1021是進(jìn)程號(hào)pid的示例,具體進(jìn)程號(hào)請(qǐng)使用前面提到的命令查看

可以看出瀏覽器進(jìn)程所占用的內(nèi)存會(huì)隨著網(wǎng)頁(yè)數(shù)量增對(duì)而增加,進(jìn)程在占用內(nèi)存達(dá)到 300M 至 400M 時(shí)會(huì)崩潰。在增大 basewebwebviewbundle.json 中的 ram 值后,最大占用內(nèi)存可達(dá)到 600M 至 700M,此時(shí)瀏覽器雖然不會(huì)崩潰,但是整機(jī)會(huì)變得非???,已經(jīng)無法使用。研究過相關(guān)代碼后發(fā)現(xiàn),目前 webview 尚無自動(dòng)回收資源的接口,這就導(dǎo)致瀏覽器的網(wǎng)頁(yè)占用的資源得不到有效的釋放,進(jìn)而導(dǎo)致瀏覽器進(jìn)程占用的內(nèi)存不斷增加,最終崩潰。

具體原因是:

1.web 組件銷毀時(shí),增加的內(nèi)存無法被回收,arkui web 組件側(cè)因?yàn)閺?qiáng)指針相互引用,導(dǎo)致析構(gòu)函數(shù)沒有被調(diào)用。
2.web 內(nèi)核側(cè)的 OnDestory 接口沒有被調(diào)用,內(nèi)核側(cè)資源沒有被回收。
3.web 內(nèi)核側(cè) GPU 渲染,new 出來的 compositor 沒有被 delete。
經(jīng)過研究,webview 的內(nèi)存資源得不到釋放的情況系版本 bug,并且這個(gè)問題在最新的 master 版本和 3.2beta2 版本已修復(fù)。

6 知識(shí)分享

1.使用智能指針 shared_ptr 時(shí)要注意不可以互相引用,否則會(huì)導(dǎo)致引用數(shù)量無法清零導(dǎo)致內(nèi)存泄漏;
2.增大系統(tǒng)預(yù)設(shè) ram 可以使某些占用內(nèi)存大的 APP 使用情況得到改善,但從系統(tǒng)總體來看,這種方法存在后患,可能會(huì)引發(fā)意想不到的問題。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 內(nèi)存泄漏
    +關(guān)注

    關(guān)注

    0

    文章

    39

    瀏覽量

    9185
  • webview
    +關(guān)注

    關(guān)注

    0

    文章

    7

    瀏覽量

    3104
  • 鴻蒙
    +關(guān)注

    關(guān)注

    56

    文章

    2267

    瀏覽量

    42481
  • HarmonyOS
    +關(guān)注

    關(guān)注

    79

    文章

    1946

    瀏覽量

    29732
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    AliOS Things 維測(cè)典型案例分析 —— 內(nèi)存泄漏

    維測(cè)典型案例分析1 —— 內(nèi)存泄漏在系統(tǒng)運(yùn)行的過程中,內(nèi)存泄漏是較為常見但是很難復(fù)現(xiàn)的現(xiàn)象,一般的內(nèi)存
    發(fā)表于 10-17 11:29

    如何在鴻蒙webview上面放其它組件?

    需求:需要在鴻蒙webview上顯示一個(gè)網(wǎng)頁(yè),在webview上面再添加一個(gè)文本,但是無論怎么webview都會(huì)覆蓋掉其它組件,這個(gè)是鴻蒙
    發(fā)表于 03-28 10:00

    項(xiàng)目中webview需要傳遞token,請(qǐng)問鴻蒙webview里怎么傳遞請(qǐng)求頭?

    鴻蒙webview怎么添加請(qǐng)求頭token,類似于安卓的loadUrl(String var1, Map var2)
    發(fā)表于 03-29 10:26

    鴻蒙webview如何設(shè)置請(qǐng)求頭?

    ;, DownloadType.HOST);mWebView.loadUrl(mUrl,webviewHead);請(qǐng)問下鴻蒙webview怎么設(shè)置請(qǐng)求頭,文檔上也沒有找到誒
    發(fā)表于 05-11 11:29

    緊急!鴻蒙webview如何設(shè)置請(qǐng)求頭

    緊急!鴻蒙webview如何設(shè)置請(qǐng)求頭
    發(fā)表于 05-12 14:41

    鴻蒙webview加載不了網(wǎng)頁(yè)是為什么?

    鴻蒙webview怎么使用呢 權(quán)限給了 就是加載不了網(wǎng)頁(yè)
    發(fā)表于 06-09 09:54

    鴻蒙webview加載Vue h5失敗是什么原因?qū)е碌模?/a>

    : ignored但該H5 url在Android webview能正常加載,且鴻蒙webview能正常加載https:百度、華為論壇等其他url,唯獨(dú)加載這個(gè)vue h5 失敗,求大佬指點(diǎn)
    發(fā)表于 06-09 10:05

    C++內(nèi)存泄漏分析方法

    C++是一種非常流行的計(jì)算機(jī)編程語(yǔ)言,在使用的過程中容易出現(xiàn)內(nèi)存泄漏問題,而該問題往往難以識(shí)別。給出了一種對(duì)C++內(nèi)存泄漏問題進(jìn)行分析的方法
    發(fā)表于 11-23 11:19 ?5次下載
    C++<b class='flag-5'>內(nèi)存</b><b class='flag-5'>泄漏</b><b class='flag-5'>分析</b>方法

    內(nèi)存泄漏的特點(diǎn)和類型

    內(nèi)存的控制,因而造成了內(nèi)存的浪費(fèi)。內(nèi)存泄漏與許多其他問題有著相似的癥狀,并且通常情況下只能由那些可以獲得程序源代碼的程序員才可以分析出來。然
    的頭像 發(fā)表于 06-20 10:58 ?2723次閱讀

    鴻蒙webview的使用和JS交互

    日常我們?cè)陂_發(fā)項(xiàng)目時(shí),為了項(xiàng)目快速的開發(fā)和迭代,難免會(huì)用到H5頁(yè)面。使用鴻蒙進(jìn)行項(xiàng)目開發(fā)時(shí),也一樣免不了要加載H5頁(yè)面,在移動(dòng)開發(fā)中打開H5頁(yè)面需要使用WebView組件。同時(shí),為了和H5頁(yè)面進(jìn)行數(shù)據(jù)交換,有時(shí)候還需要借助JSBridge來實(shí)現(xiàn)客戶端與H5之間的通訊。
    的頭像 發(fā)表于 02-28 10:56 ?2362次閱讀
    <b class='flag-5'>鴻蒙</b><b class='flag-5'>webview</b>的使用和JS交互

    什么是內(nèi)存泄漏內(nèi)存泄漏有哪些現(xiàn)象

    內(nèi)存泄漏幾乎是很難避免的,不管是老手還是新手,都存在這個(gè)問題,甚至 Windows 與 Linux 這類系統(tǒng)軟件也或多或少存在著內(nèi)存泄漏。
    的頭像 發(fā)表于 09-05 17:24 ?9469次閱讀

    什么是內(nèi)存泄漏?如何避免JavaScript內(nèi)存泄漏

    JavaScript 代碼中常見的內(nèi)存泄漏的常見來源: 研究內(nèi)存泄漏問題就相當(dāng)于尋找符合垃圾回收機(jī)制的編程方式,有效避免對(duì)象引用的問題。
    發(fā)表于 10-27 11:30 ?273次閱讀
    什么是<b class='flag-5'>內(nèi)存</b><b class='flag-5'>泄漏</b>?如何避免JavaScript<b class='flag-5'>內(nèi)存</b><b class='flag-5'>泄漏</b>

    線程內(nèi)存泄漏問題的定位

    記錄一個(gè)關(guān)于線程內(nèi)存泄漏問題的定位過程,以及過程中的收獲。 1. 初步定位 是否存在內(nèi)存泄漏:想到內(nèi)存
    的頭像 發(fā)表于 11-13 11:38 ?508次閱讀
    線程<b class='flag-5'>內(nèi)存</b><b class='flag-5'>泄漏</b>問題的定位

    如何發(fā)現(xiàn)內(nèi)存泄漏

    檢測(cè)兩個(gè)角度介紹在 Linux 環(huán)境進(jìn)行內(nèi)存泄漏檢測(cè)的方法,并重點(diǎn)介紹靜態(tài)分析工具 BEAM、動(dòng)態(tài)監(jiān)測(cè)工具 Valgrind 和 rational purify 的使用方法。相信通過本文的介紹,能給大家對(duì)處理其它產(chǎn)品或項(xiàng)目
    的頭像 發(fā)表于 11-13 15:41 ?484次閱讀

    C語(yǔ)言內(nèi)存泄漏問題原理

    內(nèi)存泄漏問題只有在使用堆內(nèi)存的時(shí)候才會(huì)出現(xiàn),棧內(nèi)存不存在內(nèi)存泄漏問題,因?yàn)闂?/div>
    發(fā)表于 03-19 11:38 ?386次閱讀
    C語(yǔ)言<b class='flag-5'>內(nèi)存</b><b class='flag-5'>泄漏</b>問題原理