App内存优化

一、内存优化介绍

1.背景介绍

  • 内存是大问题但缺乏关注
  • 压实骆驼的最后一个稻草(堆栈溢出)

2.内存问题

  • 内存抖动:锯齿状、GC导致卡顿
  • 内存泄露:可用内存减少、频繁GC
  • 内存溢出:OOM,程序异常

二、优化工具选择

1.工具选择

Memory Profiler

  • 实时图标展示应用内存使用量

  • 识别内存泄露、抖动等

  • 提供捕获堆转储、强制GC以及跟踪内存分配的能力

    总结
  • 方便直观

  • 线下平时使用

Memory Analyzer

  • 强大的Java Heap 分析工具,查找内存泄露及内存占用
  • 生成整体报告、分析问题等
  • 线下深入使用

LeakCanary

  • 自动内存泄露检测
  • https://github.com/square/leakcanary
  • 线下集成

三、Android 内存管理机制

一、Java 内存管理机制

Java 内存分配

  • 方法区:存储类信息,常量、静态变量等,如 public static final 的一些变量、常量。所有线程共享
  • 虚拟机栈:存储局部变量和操作数栈的(为Java方法服务的)
  • 本地方法栈:(为native 方法服务的)
  • 堆:几块内存块中最大的内存。所有线程共享,对象的内存分配实际上都是在堆上分配的。在虚拟机栈上分配的都是引用,会指向在堆中创建的真正的对象。是GC主要作用的一块区域。常说的内存泄露也是发送在堆上的。
  • 程序计数器:存储当前线程执行方法执行到第几行

Java 内存回收算法

标记-清除算法
  • 标记出所有需要回收的对象

  • 统一回收所有被标记的对象

    在这里插入图片描述
    缺点

  • 标记和清除效率不高

  • 产生大量不连续的内存碎片

复制算法
  • 将内存划分为大小相同的两块
  • 一块内存用完之后复制存活对象到另一块
  • 清理另一块内存
    在这里插入图片描述优缺点
  • 实现简单,运行高效(相比标记-清除算法)
  • 浪费一半空间,代价大
标记-整理算法
  • 标记过程与 “标记-清除” 算法一样
  • 存活对象王一端进行移动
  • 清理其余内存
    在这里插入图片描述
    优点
  • 避免标记-清除导致的内存碎片
  • 避免复制算法的空间浪费
分代收集算法
  • 结合多种收集算法优势
  • 新生代对象存活率低,使用复制算法
  • 老年代对象存活率高,使用标记-整理算法

二、Android内存管理机制

  • 内存弹性分配,分配值与最大值受具体设备影响
  • OOM场景:设备内存真正不足、可用内存不足(设备内存不足以分配给当前应用)

Dalvik 与 ART 区别

  • Dalvik 仅固定一种回收算法
  • Art 回收算法可以运行期选择回收算法(5.0之后都是Art)
  • Art 具备内存整理能力,减少内存空洞

Low Memory Killer 机制

针对所有进程来说的,当手机内存不足的情况下,Low Memory Killer 机制会针对所有进程进行一个回收,按照进程分配优先级顺序,找低优先进程进行回收。同时也会考虑回收收益。例如回收一个进程是30兆还是300兆

进程分类

  1. 前台进程
  2. 可见进程
  3. 服务进程
  4. 后台进程
  5. 空进程

四、内存抖动解决实战

内存抖动介绍

定义:内存频繁分配和回收导致内存不稳定
表现:频繁GC、内存曲线呈锯齿状
危害:导致卡顿、OOM

内存抖动导致OOM

  • 频繁创建对象,导致内存不足及碎片(不连续)
  • 不连续的内存片无法被分配,导致OOM

内存抖动解决实战

使用Memory Profiler 初步排查

在这里插入图片描述

使用Memory Profiler 或Cpu Profiler 结合代码排查

在这里插入图片描述

内存抖动解决技巧

  • 找循环或者频繁调用的地方

五、内存泄露解决实战

内存泄露介绍

定义:内存中存在已经没有用的对象
表现:内存抖动、可用内存逐渐减少
危害;内存不足、GC频繁、OOM

内存泄露解决实战

Memory Analyzer

  • https://www.eclipse.org/mat/downloads.php
  • 转换命令:hprof-conv 原文件路径 转换后文件路径

总结

  1. 使用Memory Profiler 初步观察(可用内存逐渐减少时,可以断定有内存泄露)
  2. 通过Memory Analyzer 结合代码确认

六、全面理解MAT

七、ARTHook 优雅检测不合理图片

Bitmap 内存模型

  • Api10 之前Bitmap 自身在Dalvik Heap 中,像素在native (有一个坏处,java 层内存回收后,native 层不知道)
  • Api10 之后像素也被放在Dalvik Heap 中
  • Api 26之后像素在Native(增加了java 向native 层的通知机制)

获取Bitmap 占用内存

  • getByteCount
  • 宽 x 高 x 一像素占用内存

常规检测不合理图片方式

背景:图片对内存优化至关重要、图片宽高大于控件宽高
实现:继承ImageView ,覆写实现计算大小
缺点:侵入性强、不通用

ARTHook 实战

介绍

挂钩,将额外的代码钩住原有方法,修改执行逻辑

  • 运行时插桩
  • 性能分析

Epic

  • Epic 是一个虚拟机层面、以Java Method 为粒度的运行时Hook 框架
  • 支持Android 4.0- 9.0
  • https://github.com/tiann/epic
使用
  1. compile ‘me.weishu:epic:0.3.6’
  2. 继承XC_MethodHook ,实现相应逻辑
  3. 注入Hook:DexposedBridge.findAandHookMethod
优点

无侵入性
通用性强
兼容问题大,开源方案不能带到线上环境

线上内存监控方案

常规方案

方案一

  • 设定场景线上Dump : Debug.dumpHprofData()
    (假设线上app 以使用单个程序最大占用内存的80%时,进行下线上内存Dump )
    在这里插入图片描述

方案一总结

  • Dump 文件太大(Dump 文件大小跟程序使用时长有关),和对象数正相关,可裁剪
  • 上传失败率高,分析困难
  • 配合一定策略,有一定效果

**

方案二

  1. LeakCanary 带到线上
  2. 预设泄露怀疑点
  3. 发现泄露回传

方案二总结

  • 不适合所有情况,必须预设怀疑点
  • 分析比较耗时、也容易OOM

LeakCanary原理

  • 监控生命周期,onDestroy 添加RefWatcher 检测
  • 二次确认断定发生内存泄露
  • 分析泄露,找引用链
  • 由监控组件 + 分析组件组成

LeakCanary 定制

  • 预设怀疑点 —> 自动找怀疑点
  • 分析泄露链路慢 ----> 分析Retain size(占用内存) 大的对象
  • 分析OOM ----> 对象裁剪,不全部加载到内存

线上监控完整方案

  • 待机内存、重点模块内存、OOM率
  • 整体及重点模块GC次数、GC 时间
  • 增强的LeakCanary 自动化内存泄露分析

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

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

相关文章

小程序的分包加载具体流程

在小程序项目的 app.json 文件中配置分包信息。通过设置 subpackages 字段,指定每个分包的根目录路径和分包的名称。 "subpackages": [{"root": "subpackage1","name": "subpackage1"},{"root": &quo…

FreeRTOS简介

FreeRTOS简介 文章目录 FreeRTOS简介前言一、什么是FreeRTOS?二、FreeRTOS的特点三、FreeRTOS的版本和参考资料1、FreeRTOS版本2、FreeRTOS源码获取3、FreeRTOS参考资料 四、FreeRTOS源码简介 前言 FreeRTOS是一个可以基于ROM运行的、可裁剪的、抢占式、实时多任务…

Photoshop最新版PS2024安装使用 Ver25.0.0

Photoshop,这个是长红了几十年的软件,我大概从它的3.0版本开始用,目前已迭代到25.0,但一直还在用CS4/11.0版本,一直秉持着够用即可的原则,因为不是专业的平面设计人员,能够简单PP图片就行。&…

C++智能指针及简单实现

C智能指针 堆内存、栈内存与静态内存静态内存栈内存堆内存 动态内存管理new、delete运算符智能指针实现智能指针 shared_ptr智能指针的线程安全问题解决 unique_ptrweak_ptr循环引用 思维导图本模块思路 动态内存管理 - cppreference.com 堆内存、栈内存与静态内存 静态内存 …

视觉测量基础

1. 相机模型 1.1 坐标系转换原理 世界坐标系(world Coords):点在真实世界中的位置,描述相机位置。 相机坐标系(Cameras Coords):以相机光学系统中心(镜头中心)为原点,建立相机坐标系。 图像物理坐标系(Film Coords):经过小孔成…

21 俄罗斯套娃信封问题

问题描述,给你一个二维数组envelopes,其中envelopes[i][wi,hi].表示第i个信封的宽度和高度,当另一个信封的宽度和噶度都比这个信封大的时候就可以放进另一个信封里,如同俄罗斯套娃一样。请计算最多能有多少个信封能组成一套“俄罗…

Debugging Application Engine Programs 调试应用程序引擎程序

Debugging Application Engine Programs 调试应用程序引擎程序 This section discusses how to: 本节讨论如何: Enable the Application Engine debugger.启用应用程序引擎调试器。Set debugging options.设置调试选项。 Enabling the Application Engine Debu…

Java数组面试题

Java数组面试题 1. 创建一个包含多个元素的数组,并打印输出数组的内容。 public class Main {public static void main(String[] args) {String[] array {"apple", "banana", "orange"};for (String element : array) {System.out…

微服务实战系列之J2Cache

前言 经过近几天陆续发布Cache系列博文,博主已对业界主流的缓存工具进行了基本介绍,当然也提到了一些基本技巧。相信各位盆友看见这么多Cache工具后,在选型上一定存在某些偏爱: A同学说:不管业务千变万化,我对Redis的…

【华为OD题库-070】数列描述-java

题目 题目描述: 有一个数列A[n],从A[0]开始每一项都是一个数字,数列中A[n1]都是A[n]的描述,其中A[0]1,规则如下; A[0]:1 A[1]:11 含义其中A[0]1是1个1即11,表示A[0]从左到右连续出现了1次1 A[2]:21 含义其中A[1]11是2个…

企业如何制定精准营销策略?

在当今的数字化时代,位置数据已经成为企业营销策略中不可或缺的一部分。通过收集和分析客户的位置数据,企业可以更好地了解客户的行为和需求,制定更精准的营销策略,从而提高营销效率。 首先,利用IP地址位置数据可以帮助…

手搓图片滑动验证码_JavaScript进阶

手搓图片滑动验证码 背景代码效果图展示网站 背景 在做前端项目开发的时候,少不了登录注册部分,既然有登录注册就少不了机器人验证,验证的方法有很多种,比如短信验证码、邮箱验证码、图片滑动、图片验证码等。 由于鄙人在开发中…

9个Logo素材超多的Logo网站!

Logo 虽然看起来很简单,但是设计过程中的每一个细节都很精致。因为 Logo 作为品牌的象征,应该一目了然地传达给人们品牌的理念和形象。本文给大家整理了 7 个 Logo 素材网站和 2 个 Logo 在线制作网站。可以收集很多关 Logo 设计的内容和技巧&#xff01…

吉他初学者学习网站搭建系列(5)——如何做一个在线节拍器

文章目录 背景实现TransportLoop代码 在线尝试 背景 我们看吉他谱时,经常看到拍号,例如6/8。它的含义是一拍是一个八分音符,一小节有六拍。四分音符的时长是一秒,即60拍/分钟。基于这样的背景知识,我们就可以根据一些…

决策树 C4.5算法

C4.5算法 C4.5算法 C4.5 算法是 Ross 对ID3 算法的改进用信息增益率来选择属性。ID3选择属性用的是子树的信息增益而C4.5用的是信息增益率在决策树构造过程中进行剪枝对非离散数据也能处理能够对不完整数据进行处理 信息增益比(C4.5) g R ( D , A ) …

Leetcode 第 110 场双周赛 Problem D 2809. 使数组和小于等于 x 的最少时间(DP+贪心+正难则反)

Leetcode 第 110 场双周赛 Problem D 2809. 使数组和小于等于 x 的最少时间&#xff08;DP 好题&#xff09;题目 给你两个长度相等下标从 0 开始的整数数组 nums1 和 nums2 。每一秒&#xff0c;对于所有下标 0 < i < nums1.length &#xff0c;nums1[i] 的值都增加 num…

supervisor管理python进程

前言 平时开发调试中使用conda环境&#xff0c;项目比较多环境多&#xff0c;而且命令繁杂&#xff0c;每一次启动项目都可能会因为忘记启动方式而频繁报错。现在可以通过supervisor来管理&#xff0c;只需要配置几个文件&#xff0c;就可以轻松通过简单一致的命令启动工程&…

C++ day55 判断子序列 不同的子序列

题目1&#xff1a;392 判断子序列 题目链接&#xff1a;判断子序列 对题目的理解 判断字符串s是否为t的子序列 字符串s和字符串t的长度大于等于0&#xff0c;字符串s的长度小于等于字符串t的长度&#xff0c;本题其实和最长公共子序列的那道题很相似&#xff0c;相当于找两…

HashMap相关专题

前置知识&#xff1a;异或运算 异或运算介绍 异或有什么神奇之处&#xff08;应用&#xff09;&#xff1f; &#xff08;1&#xff09;快速比较两个值 &#xff08;2&#xff09;我们可以使用异或来使某些特定的位翻转&#xff0c;因为不管是0或者是1与1做异或将得到原值的相…

IntelliJ IDEA 2023.2新特性详解第三弹!Docker、Kubernetes等支持!

9 Docker 在 Docker 镜像层内预览文件 现在可以在 Services&#xff08;服务&#xff09;工具窗口中轻松访问和预览 Docker 镜像层的内容。 从列表选择镜像&#xff0c;选择 Show layers&#xff08;显示层&#xff09;&#xff0c;然后点击 Analyze image for more informati…