1 關(guān)鍵字
webview;內(nèi)存泄漏
2 問(wèn)題描述
問(wèn)題現(xiàn)象:在 3.1release 版本和 3.2bete1 版本中,在 RK3568 上使用 etsWeb 和其他瀏覽器時(shí),webview 所占的內(nèi)存會(huì)隨著使用而不斷增大,最終導(dǎo)致瀏覽器 APP 因內(nèi)存泄漏而崩潰。
3 問(wèn)題原因
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 的過(guò)程如下
//文件路徑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?gfx::AcceleratedWidget, ui::Compositor*??>
CefRenderWidgetHostViewOSR::compositor_map_;
std::unordered_map?gfx::AcceleratedWidget, uint32_t??> 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) ?< "compositor construct, widget = " ?< static_cast?uint32_t??>(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) ?< "ReleaseCompositor";
if(--accelerate_widget_map_[browser_impl_-??>GetAcceleratedWidget()] == 0) {
if (!browser_impl_) {
return;
}
LOG(INFO) ?< "ReleaseCompositor, widget = " ?< static_cast?uint32_t??>(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 定位過(guò)程
在 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)無(wú)法使用。研究過(guò)相關(guān)代碼后發(fā)現(xiàn),目前 webview 尚無(wú)自動(dòng)回收資源的接口,這就導(dǎo)致瀏覽器的網(wǎng)頁(yè)占用的資源得不到有效的釋放,進(jìn)而導(dǎo)致瀏覽器進(jìn)程占用的內(nèi)存不斷增加,最終崩潰。
具體原因是:
1.web 組件銷毀時(shí),增加的內(nèi)存無(wú)法被回收,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 出來(lái)的 compositor 沒有被 delete。
經(jīng)過(guò)研究,webview 的內(nèi)存資源得不到釋放的情況系版本 bug,并且這個(gè)問(wèn)題在最新的 master 版本和 3.2beta2 版本已修復(fù)。
6 知識(shí)分享
1.使用智能指針 shared_ptr 時(shí)要注意不可以互相引用,否則會(huì)導(dǎo)致引用數(shù)量無(wú)法清零導(dǎo)致內(nèi)存泄漏;
2.增大系統(tǒng)預(yù)設(shè) ram 可以使某些占用內(nèi)存大的 APP 使用情況得到改善,但從系統(tǒng)總體來(lái)看,這種方法存在后患,可能會(huì)引發(fā)意想不到的問(wèn)題。
-
內(nèi)存泄漏
+關(guān)注
關(guān)注
0文章
39瀏覽量
9190 -
webview
+關(guān)注
關(guān)注
0文章
7瀏覽量
3115 -
鴻蒙
+關(guān)注
關(guān)注
57文章
2287瀏覽量
42629 -
HarmonyOS
+關(guān)注
關(guān)注
79文章
1954瀏覽量
29897
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論