App内存优化

news2024/11/28 6:28:39

一、内存优化介绍

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.coloradmin.cn/o/1286654.html

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

相关文章

【C语言】函数递归详解(二)

前言 在上一篇博客函数递归详解(一)中讲解了什么是递归,递归的思想及限制条件以及两个递归的例子,这一篇博客将讲解递归与迭代的关系。 递归与迭代 递归是一种很好的编程技巧,但是同很多技巧一样也是可能被误用的&…

api 网关

API网关 什么是网关? 微服务背景下,一个系统被拆分为多个服务,但是像安全认证,流量控制,日志,监控等功能是每个服务都需要的,没有网关的话,我们就需要在每个服务中单独实现&#x…

2023年【T电梯修理】考试总结及T电梯修理证考试

题库来源:安全生产模拟考试一点通公众号小程序 T电梯修理考试总结考前必练!安全生产模拟考试一点通每个月更新T电梯修理证考试题目及答案!多做几遍,其实通过T电梯修理证考试很简单。 1、【多选题】《特种设备安全法》规定&#x…

【2】PyQt创建窗口

1. 第一个PyQt窗口 from PyQt5.QtWidgets import QApplication,QWidget import sys# 1.创建应用程序 app QApplication(sys.argv)# 2.创建窗口 w QWidget()# 3.显示窗口 w.show()# 4.等待窗口停止 sys.exit(app.exec()) 执行代码,就会显示PyQt窗口: 2. PyQt模块简介 PyQt中…

基于SpringBoot的校园互助网站

简介 本系统分为三个角色,分别是普通用户和管理员、以及超级管理员,主要的功能模块有注册、登录、物品代购、快递代取、话题管理、任务管理、反馈管理、投诉管理、订单管理等功能模块。 项目 数据库 首页 登录 新增反馈 发布话题 发布任务 接单 我要投诉…

粒子群优化算法的实践

粒子群优化算法的实践 flyfish 粒子群优化算法(Particle Swarm Optimization,PSO)或者粒子群算法 红叉的地方是理想之地,这些粒子都想去,总结8个字是信息共享,个人决策。 上完图之后,上代码&a…

算法通关村——数论问题

数论是一个很重要的学科,覆盖领域极广,小到小学的智力问题,大到世界顶级科学家都一直在研究相关问题,因此其难度跨度非常大。在程序设计里 ,也经常会出现数论的问题,但是,这些一般都是比较基本的…

训练自己的YOLOv8姿态估计模型

在不断发展的计算机视觉领域,姿态估计作为一项关键创新脱颖而出,改变了我们理解视觉数据以及与视觉数据交互的方式。 Ultralytics YOLOv8 处于这一转变的最前沿,提供了一个强大的工具来捕捉图像中物体方向和运动的微妙之处。 NSDT工具推荐&am…

Avalonia开发之HelloWrold

前言 本文所有讲解是以VS2022为开发工具,官方提供了VS2022和2019的扩展支持,大家根据自己的是实际情况下载相应的扩展进行安装。 安装扩展 如下图,我们在扩展菜单里面找到扩展管理,如下图: 在扩展管理的搜索栏里面…

解决:docx.opc.exceptions.PackageNotFoundError: Package not found at ‘xxx’

解决:docx.opc.exceptions.PackageNotFoundError: Package not found at ‘xxx’ 文章目录 解决:docx.opc.exceptions.PackageNotFoundError: Package not found at ‘xxx’背景报错问题报错翻译报错位置代码报错原因解决方法今天的分享就到此结束了 背景…

MIT_线性代数笔记:第 12 讲 图、网络、关联矩阵

目录 图和网络 Graphs & Networks关联矩阵(Incidence matrices)矩阵的零空间矩阵列空间矩阵的左零空间矩阵的行空间 本讲讨论线性代数在物理系统中的应用。 图和网络 Graphs & Networks “图”就是“结点”和“边”的一个集合。 边线上的箭头代…

js实现AES加密解密,简易又全面

常规是直接安装CryptoJS库,但为了减少项目体积,使用这简单的20k文件就ok 一览: 代码中使用的是Pkcs7,但我需要的填充方式是ZeroPadding 所以稍微有修改: q (p.pad {}).ZeroPadding {pad: function (data, blockSi…

波奇学C++:类型转换和IO流

隐式类型转换 int i0; double pi; 强制类型转换 int* pnullptr; int a(int)p; 单参数构造函数支持隐式类型转换 class A { public:A(string a):_a(a){} private:string _a; }; A a("xxxx"); //"xxx" const char* 隐式转换为string 多参数也可以通过{…

c语言指针详解(上)

目录 一、指针的基本概念和用法 二、指针运算 2.1 指针的自增和自减运算 2.2 指针的自增和自减运算 三、数组和指针 四、指针和函数 4.1 在函数中使用指针作为参数和返回值 4.1.1 使用指针作为函数参数 4.1.2 使用指针作为函数返回值 4.2 指针参数的传值和传引用特性 4.2.1 指针…

Visual Studio Code tasks.json中控制任务执行问题面板显示内容的PresentationOptions介绍

☞ ░ 前往老猿Python博客 ░ https://blog.csdn.net/LaoYuanPython 一、引言 在 Visual Studio Code 中,tasks.json 文件用于配置和控制任务的执行,其中的 presentation配置项可以用来控制任务执行时在终端面板窗口中输出的内容,presentat…

单机无锁线程安全队列-Disruptor

Disruptor 1、基本介绍 说到队列,除了常见的mq中间件,java中也自带线程安全的BlockingQueue,但是BlockingQueue通过在入队和出队时加锁的方式避免并发操作,性能上会大打折扣。 而Disruptor是一个线程安全、低延迟、吞吐量高的队…

代替APP?微信小程序到底好在哪?

2019年是微信小程序宣布登场的一年,它实现了应用程序能被“垂手可得”的愿望。用户只需简单扫一扫或搜索,就能轻松打开应用。与需要在应用市场下载的APP相比,微信小程序可以在微信中被轻易地获取和传播,同时也带来了非凡的使用体验…

102.套接字-Socket网络编程4(TCP通信流程)

目录 TCP编程流程 套接字函数 1.创建套接字 2.绑定地址 3.监听连接请求 4.接受连接 5. 连接到服务器 6. 发送数据 7. 接收数据 8.关闭套接字 服务器端通信流程 示例代码 客户端通信流程 代码示例 TCP编程流程 TCP是一个面向连接的,安全的,流…

单调栈与单调队列算法总结

单调栈 知识概览 单调栈最常见的应用是找到每一个数离它最近的且比它小的数。单调栈考虑的方式和双指针类似,都是先想一下暴力做法是什么,然后再挖掘一些性质如单调性,最终可以把目光集中在比较少的状态中,从而达到降低时间复杂…

【Linux】基础IO--重定向理解Linux下一切皆文件缓冲区

文章目录 一、重定向1.什么是重定向2.dup2 系统调用3.理解输入重定向、输出重定向和追加重定向4.简易shell完整实现 二、理解linux下一切皆文件三、缓冲区1.为什么要有缓冲区2.缓冲区的刷新策略3.缓冲区的位置4.实现一个简易的C语言缓冲区5.内核缓冲区 一、重定向 1.什么是重定…