【鸿蒙】webview内存泄漏问题的分析报告

【鸿蒙】webview内存泄漏问题的分析报告

1 关键字

webview;内存泄漏

2 问题描述

问题现象:在 3.1release 版本和 3.2bete1 版本中,在 RK3568 上使用 etsWeb 和其他浏览器时,webview 所占的内存会随着使用而不断增大,最终导致浏览器 APP 因内存泄漏而崩溃。

3 问题原因

3.1 正常机制

在任意版本上使用浏览器 APP,可以长时间正常浏览网页。

3.2 异常机制

在 3.1release 和 3.2beta1 上使用浏览器 APP,长时间浏览网页后,应用会崩溃。

4 解决方案

  • arkui web 侧,在析构函数中调用 OnDestroy 方法销毁组件
    //文件路径
foundation\arkui\ace_engine\frameworks\core\***ponents\web\resource\web_delegate.cpp
WebDelegate::~WebDelegate()
{
    ReleasePlatformResource();
    if (nweb_) {
        nweb_->OnDestroy();
    }
}

  • web 内核中的 ***positor 被 delete 的过程如下
//文件路径src\cef\libcef\browser\osr\render_widget_host_view_osr.***
#include "ui/gfx/geometry/size_conversions.h"
#include "ui/touch_selection/touch_selection_controller.h"
 
// static
std::unordered_map<gfx::A***eleratedWidget, ui::***positor*>
    CefRenderWidgetHostViewOSR::***positor_map_;
 
std::unordered_map<gfx::A***eleratedWidget, uint32_t> CefRenderWidgetHostViewOSR::a***elerate_widget_map_;
 
namespace {
// The maximum number of damage rects to cache for outstanding frame requests
// (for OnA***eleratedPaint).
const size_t kMaxDamageRects = 10;
  ***positor_->SetRootLayer(root_layer_.get());
  ***positor_->AddChildFrameSink(GetFrameSinkId());
#else
  LOG(INFO) << "***positor construct, widget = " << static_cast<uint32_t>(browser_impl_->GetA***eleratedWidget());
  ui::***positor* ***positor = CefRenderWidgetHostViewOSR::Get***positor(
      browser_impl_->GetA***eleratedWidget());
  a***elerate_widget_map_[browser_impl_->GetA***eleratedWidget()]++;
  if (!***positor) {
    ***positor = new ui::***positor(
        context_factory->AllocateFrameSinkId(), context_factory,
  if (!***positor_) {
    return;  // already released
  }
#else
  if (!browser_impl_) {
    return;
  }
  auto it = a***elerate_widget_map_.find(browser_impl_->GetA***eleratedWidget());
  if (it == a***elerate_widget_map_.end()) {
    return;
  }
#endif
  // Marking the DelegatedFrameHost as removed from the window hierarchy is
  // necessary to remove all connections to its old ui::***positor.
 
  if (delegated_frame_host_) {
    if (is_showing_) {
      delegated_frame_host_->WasHidden(content::DelegatedFrameHost::HiddenCause::kOther);
    }
    delegated_frame_host_->DetachFrom***positor();
    delegated_frame_host_.reset(nullptr);
  }
 
#ifdef DISABLE_GPU
  ***positor_.reset(nullptr);
#else
  LOG(INFO) << "Release***positor";
  if(--a***elerate_widget_map_[browser_impl_->GetA***eleratedWidget()] == 0) {
    if (!browser_impl_) {
      return;
    }
    LOG(INFO) << "Release***positor, widget = " << static_cast<uint32_t>(browser_impl_->GetA***eleratedWidget());
    auto it = ***positor_map_.find(browser_impl_->GetA***eleratedWidget());
    if (it != ***positor_map_.end()) {
      if (it->second != nullptr) {
        delete it->second;
      }
      ***positor_map_.erase(it);
    }
    a***elerate_widget_map_.erase(browser_impl_->GetA***eleratedWidget());
  }
#endif
}

5 定位过程

在 RK3568 上使用 etsWeb 时,使用下列命令可以看到浏览器的进程号 pid 和进程所占内存情况。

ps -ef #查看pid
hidumper --mem 1021 #查看进程所占内存,这里的1021是进程号pid的示例,具体进程号请使用前面提到的命令查看

可以看出浏览器进程所占用的内存会随着网页数量增对而增加,进程在占用内存达到 300M 至 400M 时会崩溃。在增大 base\web\webview\bundle.json 中的 ram 值后,最大占用内存可达到 600M 至 700M,此时浏览器虽然不会崩溃,但是整机会变得非常卡,已经无法使用。研究过相关代码后发现,目前 webview 尚无自动回收资源的接口,这就导致浏览器的网页占用的资源得不到有效的释放,进而导致浏览器进程占用的内存不断增加,最终崩溃。

具体原因是:

1.web 组件销毁时,增加的内存无法被回收,arkui web 组件侧因为强指针相互引用,导致析构函数没有被调用。
2.web 内核侧的 OnDestory 接口没有被调用,内核侧资源没有被回收。
3.web 内核侧 GPU 渲染,new 出来的 ***positor 没有被 delete。
经过研究,webview 的内存资源得不到释放的情况系版本 bug,并且这个问题在最新的 master 版本和 3.2beta2 版本已修复。

6 知识分享

1.使用智能指针 shared_ptr 时要注意不可以互相引用,否则会导致引用数量无法清零导致内存泄漏;
2.增大系统预设 ram 可以使某些占用内存大的 APP 使用情况得到改善,但从系统总体来看,这种方法存在后患,可能会引发意想不到的问题。

为了能让大家更好的学习鸿蒙 (OpenHarmony) 开发技术,这边特意整理了《鸿蒙 (OpenHarmony)开发学习手册》,希望对大家有所帮助:

《鸿蒙(Harmony OS)开发学习手册》

入门必看:https://docs.qq.***/doc/DUk51cHZJaUpmSlhH
1.应用开发导读(ArKTS)
2.……

HarmonyOS概念:https://docs.qq.***/doc/DUk51cHZJaUpmSlhH
1.系统定义
2.技术框架
3.技术特性
4.系统安全

快速入门:https://docs.qq.***/doc/DUk51cHZJaUpmSlhH
1.基本概念
2.构建第一个ArkTS应用
3.……

开发基础知识:https://docs.qq.***/doc/DUk51cHZJaUpmSlhH
1.应用基础知识
2.配置文件
3.应用数据管理
4.应用安全管理
5.应用隐私保护
6.三方应用调用管控机制
7.资源分类与访问
8.学习ArkTS
9…

基于ArkTS 开发:https://docs.qq.***/doc/DUk51cHZJaUpmSlhH
1.Ability开发
2.UI开发
3.公共事件与通知
4.窗口管理
5.媒体
6.安全
7.网络与链接
8.电话服务
9.数据管理
10.后台任务(Background Task)管理
11.设备管理
12.设备使用信息统计
13.DFX
14.国际化开发
15.折叠屏系列
16………

转载请说明出处内容投诉
CSS教程_站长资源网 » 【鸿蒙】webview内存泄漏问题的分析报告

发表评论

欢迎 访客 发表评论

一个令你着迷的主题!

查看演示 官网购买