HarmonyOS优化应用内存占用问题性能优化四

一、使用purgeable优化C++内存
Purgeable Memory是HarmonyOS中native层常用的内存管理机制,可用于图像处理的Bitmap、流媒体应用的一次性数据、图片等。应用可以使用Purgeable Memory存放其内部的缓存数据,并由系统根据淘汰策略统一管理全部的purgeable内存。当系统内存不足时,系统可以通过丢弃purgeable内存快速回收内存资源,以释放更多的内存资源给其他应用程序使用,实现全局高效的缓存数据管理。这种机制可以帮助系统更有效地管理内存,提高系统的稳定性和流畅性。
在使用Purgeable内存时,开发者可以调用接口释放Purgeable内存,但需要注意在适当的时机释放Purgeable内存,以确保内存资源能够得到有效管理,避免内存占用过高导致的性能问题和内存泄漏的情况。通过合理使用Purgeable内存,开发者可以更好地管理应用程序的内存,提高用户体验。
(一)原理介绍
Purgeable内存访问流程图如下图所示,在访问Purgeable内存时,首先需要判断当前Purgeable内存的数据是否已经被回收,如果Purgeable内存已经被回收了,那么需要先重建数据再使用。在访问Purgeable内存的数据时,Purgeable内存对应的引用计数refcnt加1,在访问Purgeable结束后,其引用计数refcnt会减1,当引用计数为0的时候,该Purgeable内存可以被系统回收。
图2 Purgeable内存访问流程图
 

HarmonyOS优化应用内存占用问题性能优化四-鸿蒙开发者社区


Purgeable内存回收流程图如下所示,当引用计数为0时,丢弃掉Purgeable内存中的数据,并标识Purgeable内存已回收。
图3 Purgeable内存回收流程图
 

HarmonyOS优化应用内存占用问题性能优化四-鸿蒙开发者社区


(二)参考案例
在CMakeLists.txt文件中引入Purgeable对应的动态链接库libpurgeable_memory_ndk.z.so,具体如下所示:

# the minimum version of CMake.
cmake_minimum_required(VERSION 3.4.1)
project(MyNativeApplication)
set(NATIVERENDER_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR})
if(DEFINED PACKAGE_FIND_FILE)include(${PACKAGE_FIND_FILE})
endif()
include_directories(${NATIVERENDER_ROOT_PATH}${NATIVERENDER_ROOT_PATH}/include)
add_library(entry SHARED napi_init.cpp)
# 引入libpurgeable_memory_ndk.z.so动态链接库
target_link_libraries(entry PUBLIC libace_napi.z.so libpurgeable_memory_ndk.z.so)

    引入purgeable_memory头文件,并声明创建PurgeableMemory对象需要使用的ModifyFunc函数,调用OH_PurgeableMemory_Create创建PurgeableMemory对象。
    在读取PurgeableMemory对象的内容时,需要调用OH_PurgeableMemory_BeginRead,读取结束时,需要调用OH_PurgeableMemory_EndRead。其中,OH_PurgeableMemory_GetContent可以获取PurgeableMemory对象的内存数据。
    在修改PurgeableMemory对象的内容时,需要调用OH_PurgeableMemory_BeginWrite,读取结束时,需要调用OH_PurgeableMemory_EndWrite。其中,OH_PurgeableMemory_AppendModify可以更新PurgeableMemory对象重建规则。

    #include "napi/native_api.h"
    #define DATASIZE (4 * 1024 * 1024)
    #include "purgeable_memory/purgeable_memory.h"bool ModifyFunc(void *data, size_t size, void *param) {data = param;return true;
    }
    // 业务定义对象类型
    class ReqObj;
    static napi_value Add(napi_env env, napi_callback_info info)
    {size_t requireArgc = 2;size_t argc = 2;napi_value args[2] = {nullptr};napi_get_cb_info(env, info, &argc, args , nullptr, nullptr);napi_valuetype valuetype0;napi_typeof(env, args[0], &valuetype0);napi_valuetype valuetype1;napi_typeof(env, args[1], &valuetype1);double value0;napi_get_value_double(env, args[0], &value0);double value1;napi_get_value_double(env, args[1], &value1);double result = value0 + value1;// 创建一个PurgeableMemory对象OH_PurgeableMemory *pPurgmem = OH_PurgeableMemory_Create(DATASIZE, ModifyFunc, &result);// 读取对象OH_PurgeableMemory_BeginRead(pPurgmem);// 获取PurgeableMemory对象大小size_t size = OH_PurgeableMemory_ContentSize(pPurgmem);// 获取PurgeableMemory对象内容ReqObj *pReqObj = (ReqObj *)OH_PurgeableMemory_GetContent(pPurgmem);// 读取PurgeableMemory对象结束OH_PurgeableMemory_EndRead(pPurgmem);// 修改PurgeableMemory对象OH_PurgeableMemory_BeginWrite(pPurgmem);// 声明扩展创建函数的参数double newResult = value0 + value0;// 更新PurgeableMemory对象重建规则OH_PurgeableMemory_AppendModify(pPurgmem, ModifyFunc, &newResult);// 修改PurgeableMemory对象结束OH_PurgeableMemory_EndWrite(pPurgmem);// 销毁对象OH_PurgeableMemory_Destroy(pPurgmem);napi_value sum;napi_create_double(env, result, &sum);return sum;
    }
    EXTERN_C_START
    static napi_value Init(napi_env env, napi_value exports)
    {napi_property_descriptor desc[] = {{ "add", nullptr, Add, nullptr, nullptr, nullptr, napi_default, nullptr }};napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);return exports;
    }
    EXTERN_C_ENDstatic napi_module demoModule = {.nm_version = 1,.nm_flags = 0,.nm_filename = nullptr,.nm_register_func = Init,.nm_modname = "entry",.nm_priv = ((void*)0),.reserved = { 0 },
    };
    extern "C" __attribute__((constructor)) void RegisterEntryModule(void)
    {napi_module_register(&demoModule);
    }

      二、使用合理尺寸的图片优化应用内存
      (一)原理介绍
      应用在定义界面时,对于使用不同类型的组件,需要绘制不同的内容。图片组件主要用来加载和显示图片,而组件本身也需要占用内存。ArkTS目前采用引用计数的机制来管理内存。引用计数是一种简单而高效的内存管理方式,它通过记录每个对象被引用的次数来确定何时释放对象。需要注意的是,如果组件没有正确释放,即使其他地方不再使用该组件,对应的引用链接上的资源也不会被释放,可能会导致内存泄漏问题。
      一张全屏的图片,不同分辨率的内存占用大小如下:
       

      HarmonyOS优化应用内存占用问题性能优化四-鸿蒙开发者社区


      由上图可以看出,对于一些页面多、图片多、效果多的资源密集型应用,内存很容易达到较高水平。当应用的内存占用超过系统设定的阈值(如4G,其中4G只是示例,不同系统的阈值不同)时,系统可能会认为应用存在严重的内存问题,并可能会强制杀死该应用进程,以保证设备系统的稳定性和性能。为了避免应用被系统杀死,开发者可以考虑以下两点:
      优化资源使用:通过合理设置图片源文件大小,合理使用内存资源,减少图片所占应用内存。
      布局优化:通过减少布局嵌套层级,减少过度绘制可以产生较大的性能收益。
      本章节主要指导开发者通过合理设置图片源文件大小,合理使用内存资源,减少图片所占应用内存。
      (二)避免加载超过显示尺寸的图片

      如上代码示例中,使用500500尺寸大小的Image组件加载一张尺寸为40323024的RGBA格式图片时(每个像素占用4个字节),图片申请了约46.5M的内存。这是因为图片的原始尺寸较大,加载到Image组件中时需要将其缩放到500500的尺寸,这个过程会占用一定的内存空间。
      可使用公式计算出来纹理图片内存大小 = imageWidth x imageHeight x format(4032
      3024 * 4 = 48771072 bytes ≈ 46.5M)。
      但是实际上,组件只需要500500的尺寸。也就是说,实际需要的内存 = 500500*4 ≈ 1M。
       

      HarmonyOS优化应用内存占用问题性能优化四-鸿蒙开发者社区


      因此当一张图片比控件显示的区域要大,最终会被裁剪或者缩放。大量的裁剪和缩放不仅导致视图效果变差,还会浪费内存,引起严重的功耗问题。为了最大程度地节省内存,开发者可以手动调整源文件的尺寸大小,使其与组件的大小保持一致。这样可以避免不必要的内存浪费,并提高应用程序的性能和效率。开发者可以使用图像处理工具来调整图像的尺寸大小,从而进一步节省内存空间。

      本文主要引用参考HarmonyOS官方文档

      本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/web/81071.shtml

      如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

      相关文章

      第一课如何学习课程

      读薄就这些东西 读厚细节;实现了还是很混沌(内功心法)-》有个项目;在听的过程中写博客:我学了什么,敲代码; 第二章 网络-》9.1kv存储 第三章 基础组件 (API函数、最基础的底层架构…

      Linux 系统不终止进程的情况下关闭长连接

      使用 tcpkill 中断指定 TCP 连接 适用场景:需主动中断已知源IP或目标端口的连接,无需进程重启。 安装 dsniff 工具(包含 tcpkill): yum -y install dsniff 捕获并杀死特定连接(例如目标IP 192.168.1.10…

      TCP原理解析

      目录 TCP协议概述 1. 基础寻址段​​ ​​2. 序列控制段​​ ​​3. 控制信息段​​ ​​4. 流量控制段​​ ​​5. 校验与应急段​​ ​​6. 扩展功能段​​ ​​7. 数据承载段​​ TCP原理 确认应答与序列号(安全机制) 超时重传机制(安全机制) 连接管理机制&…

      抛弃传统P2P技术,EasyRTC音视频基于WebRTC打造教育/会议/远程巡检等场景实时通信解决方案

      一、方案背景 随着网络通信发展,实时音视频需求激增。传统服务器中转方式延迟高、资源消耗大,WebP2P技术由此兴起。EasyRTC作为高性能实时通信平台,集成WebP2P技术,实现低延迟、高效率音视频通信,广泛应用于教育、医疗…

      2025年度消费新潜力白皮书470+份汇总解读|附PDF下载

      原文链接:https://tecdat.cn/?p42178 过去一年,消费市场在政策驱动与技术迭代中呈现结构性变革。社零总额达487,895亿元,实物商品网零额占比27%,线上渠道成为增长引擎。本报告从食品饮料、美妆护肤、家电数码、服饰户外四大核心领…

      “智”造巨轮启新程:数字安全的战略布局

      数据就像空气,无处不在;安全就像呼吸,刻不容缓! 在智能化不断创新的沃土上,某大型智能家电企业这艘智造巨轮正乘风破浪,驶向数字化的深蓝大海。作为全球家电制造的领航者,深知:在这个数字时代&a…

      React组件(二):常见属性和函数

      文章目录 一、defaultProps 和 prop-types使用 defaultProps 设置组件的默认值使用prop-types进行props数据类型的校验代码举例 二、事件绑定原生js做事件绑定使用 React 提供的方法,做事件绑定 三、生命周期函数:shouldComponentUpdate()四、在js代码中…

      redis 进行缓存实战-18

      使用 Redis 进行缓存 Redis 通常被认为只是一个数据存储,但它的速度和内存中特性使其成为缓存的绝佳选择。缓存是一种技术,通过将经常访问的数据存储在快速的临时存储位置来提高应用程序性能。通过使用 Redis 作为缓存,您可以显著减少主数据…

      【Nginx学习笔记】:Fastapi服务部署单机Nginx配置说明

      服务部署单机Nginx配置说明 服务.conf配置文件: upstream asr_backend {server 127.0.0.1:8010; }server {listen 80;server_name your_domain.com;location / {proxy_pass http://localhost:8000;proxy_set_header Host $host;proxy_set_header X-Real-IP $remot…

      Qt网络编程

      前言 Qt为了支持跨平台,对系统网络编程的API(socket API)也进行了重新分装。 实际Qt中进行网络编程也不一定使用Qt封装的网络API,也有可能使用的是系统原生API或者其他第三方框架的API。 若要使用Qt中的网络编程的API&#xff…

      矩阵短剧系统:如何用1个后台管理100+小程序?技术解析与实战应用

      引言:短剧行业的效率革命 2025年,短剧市场规模已突破千亿,但传统多平台运营模式面临重复开发成本高、用户数据分散、内容同步效率低等痛点。行业亟需一种既能降本增效又能聚合流量的解决方案——“矩阵短剧系统”。通过“1个后台管理100小程…

      嵌入式STM32学习——ESP8266 01S的基础介绍

      简介 ESP8266 系列模组是深圳市安信可科技有限公司开发的一系列基于乐鑫ESP8266EX的低功耗UART-WiFi芯片模组,可以方便地进行二次开发,接入云端服务,实现手机3/4G全球随时随地的控制,加速产品原型设计。 模块核心处理器 ESP8266 在…

      form-create-designer中$inject参数的数据结构及各项属性说明

      FcDesigner 是一款基于Vue的开源低代码可视化表单设计器工具,通过数据驱动表单渲染。可以通过拖拽的方式快速创建表单,提高开发者对表单的开发效率,节省开发者的时间。并广泛应用于在政务系统、OA系统、ERP系统、电商系统、流程管理等领域。 …

      Jasypt概述及整合SpringBoot实现敏感数据加密

      前言 在实际开发中,Spring Boot应用的配置文件中经常包含数据库密码、API密钥等敏感信息。如果这些信息以明文形式存储,会带来严重的安全隐患。本文将详细介绍如何使用Jasypt(Java Simplified Encryption)对Spring Boot配置文件中…

      Better Faster Large Language Models via Multi-token Prediction 原理

      目录 模型结构: Memory-efficient implementation: 实验: 1. 在大规模模型上效果显著: 2. 在不同类型任务上的效果: 为什么MLP对效果有提升的几点猜测: 1. 并非所有token对生成质量的影响相同 2. 关…

      git merge解冲突后,add、continue提交

      git merge解冲突后,add、continue提交 git merge操作冲突后,需要手动解冲突,解完冲突后,需要: git add . 然后,进入一般的正常git代码提交流程。 git合并‘merge’其他分支的个别文件到当前branch_gitbash 合并branc…

      3.8.1 利用RDD实现词频统计

      在本次实战中,我们通过Spark的RDD实现了词频统计功能。首先,准备了包含单词的文件并上传至HDFS。接着,采用交互式方式逐步完成词频统计,包括创建RDD、单词拆分、映射为二元组、按键归约以及排序等操作。此外,还通过创建…

      应对进行性核上性麻痹,健康护理铸就温暖防线

      进行性核上性麻痹(PSP)是一种罕见的神经退行性疾病,主要影响患者的运动、平衡及吞咽等功能。针对这类患者,有效的健康护理对提升其生活质量、延缓病情发展至关重要。 在日常生活护理方面,由于患者存在平衡障碍和肌肉僵…

      融合蛋白质语言模型和图像修复模型,麻省理工与哈佛联手提出PUPS ,实现单细胞级蛋白质定位

      蛋白质亚细胞定位(subcellular localization of a protein)是指蛋白质在细胞结构中具体的定位情况, 这对蛋白质行使其生物学功能至关重要。举个简单例子,如果把细胞想象成一个庞大的企业,其中细胞核、线粒体、细胞膜等…

      lanqiaoOJ 4330:欧拉函数模板

      【题目来源】 https://www.lanqiao.cn/problems/4330/learning/ 【问题描述】 这是一道模板题。 首先给出欧拉函数的定义:即 φ(n) 表示的是小于等于 n 的数中和 n 互质的数的个数。 比如说 φ(6)2,当 n 是质数的时候,显然有φ(n)n-1。 【题…