Android 内存优化内存泄漏处理

一:匿名内部类/非静态内部类

匿名内部类的泄漏原因:匿名内部类会隐式地持有外部类的引用.当外部类被销毁时,内部类并不会自动销毁,因为内部类并不是外部类的成员变量,
它们只是在外部类的作用域内创建的对象,所以内部类的销毁时机和外部类的销毁时机是不同的,
所以会不会取决与对应对象是否存在被持有的引用.

 案例一:有名内部类导致内存泄漏

匿名内部类/非静态内部类,Android开发经常会继承实现 Activity 或者 Fragment 或者 View。
如果你使用了匿名类,而又被异步线程所引用,那得小心,如果没有任何措施同样会导致内存泄漏的.

runnable1 和 runnable2 的区别就是,runnable2 使用了匿名内部类,我们看看引用时的引用内存:

可以看到,runnable1 是没有什么特别的。但 runnable2 多出了一个 MainActivity 的引用,若是这个引用再传入到一个异步线程,此线程在和Activity生命周期不一致的时候,也就造成了Activity的泄露。

在 MainActivity 内部创建了一个非静态内部类的单例TestInnerBad,不过这种写法却会造成内存泄漏,非静态内部类默认会持有外部类MainActivity 的引用,导致 MainActivity的内存资源不能正常回收.

解决方案:

 将该内部类TestInnerBad设为静态内部类或将该内部类抽取出来封装成一个单例,

案例二:匿名内部类导致内存泄漏

public class TestActivity {public static void main(String[] args) {//java的匿名内部类 new Thread(new Runnable() {@Overridepublic void run() {}}).start();}
}

匿名内部类Runnable持有外部类TestActivity 的引用, 当外部类TestActivity销毁时,匿名内部类Runnable 会导致内存泄漏,

解决方案:

创建一个静态内部类实现Runnable接口或者使用lambda表达式

public class TestActivity {Runnable runnable1public static void main(String[] args) {runnable1 = new MyRunnable()new Thread(runnable1).start();}//创建一个静态内部类
private static class MyRunnable implements Runnable{@Overridepublic void run(){
}
}@overRide  
onDestroy(){runnable1=null }}
 java:  把Runnable转为lambda写法   避免了内存泄漏 new Thread(() -> { }).start();

 

kotlin:  把Runnable转为lambda写法   避免了内存泄漏Thread({}).start()
或者
Thread {}.start()

案例三:匿名内部类导致内存泄漏

public class MyActivity extends Activity {private Button button;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);button = new Button(this);button.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// do something}});setContentView(button);}
}

匿名内部类OnClickListener持有了外部类MyActivity的引用,如果MyActivity被销毁之前,button没有被清除,
 就会导致MyActivity无法被垃圾回收。(此处可以将Button 看作是自己定义的一个对象,
 一般解法是将button对象置为空)

 注意事项:在Activity销毁时,应该将所有持有Activity引用的对象设置为null。

二:静态变量

当我们的成员变量是 static 的时候,那么它的生命周期将和整个app的生命周期一致。这必然会导致一系列问题,

 解决方案:

不要在类初始时初始化静态成员。可以考虑 lazy初始化(延迟加载)

三:单例Singleton

单例的静态特性,使得它的生命周期和应用的生命周期会一样长,所以一旦使用有误,小心无限制的持有Activity的引用而导致内存泄漏。

public class MySingleton {private static MySingleton instance;private Context context;private  MySingleton(Context context){this.context=context
}public static MySingleton getInstance(Context context) {if (instance == null) {instance = new MySingleton(Context context);}return instance;}// ...
}

  如果我们传入的是 Activity 的 Context,当这个 Context 所对应的 Activity 退出的时候,由于该 Context 的引用被单例对象所持有,其生命周期等于整个应用程序的生命周期,所以当前 Activity 退出时它的内存并不会回收,这造成的内存泄漏

解决方案: 使用 Application 的 Context 避免内存泄漏


public class MySingleton {private static MySingleton instance;private Context context;private  MySingleton(Context context){// this.context=context//   使用 Application 的 Context 避免内存泄漏this.context=context.getApplicationContext()}public static MySingleton getInstance(Context context) {if (instance == null) {synchronized (MySingleton.class) {if (instance == null) {instance = new MySingleton(Context context);}}}return instance;}public static void releaseInstance() {instance = null;}// ...
}

 

四:Context

如果需要使用 Context,推荐的使用 Application 的 Context。当然,Application 的 context  不是万能的,所以也不能随便乱用,对于有些地方则必须使用 Activity 的 Context,对于Application,Service,Activity三者的 Context 的应用场景如下:

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

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

相关文章

力扣细节题:翻转二叉树

细节一:递归采用前序递归 细节二:采用交换节点而不是交换数据因为左右树交换的同时左右树的所有子节点都要交换 细节三:采用外置函数因为return如果在本函数内操作会存在必须返回空指针的问题 /*** Definition for a binary tree node.* s…

01_02_mysql09_MySQL的数据目录

MySQL的数据目录 学习再总结宋红康老师课程内容1.MySQL8的主要目录结构 安装好MySQL8之后,查看如下的目录结构 find / -name mysql1.1数据库文件的存放路径 MySQL数据库文件的存放路径:/var/lib/mysql/ 1.2相关命令目录 相关命令目录:/u…

番外篇 | YOLOv5+DeepSort实现行人目标跟踪检测

前言:Hello大家好,我是小哥谈。DeepSort是一种用于目标跟踪的深度学习算法。它结合了目标检测和目标跟踪的技术,能够在视频中准确地跟踪多个目标,并为每个目标分配一个唯一的ID。DeepSort的核心思想是将目标检测和目标跟踪两个任务进行联合训练,以提高跟踪的准确性和稳定性…

创建vue3项目(基础)

首先打开自己的目录文件输入指令cmd 出现命令行工具 输入指令vue create 项目名称 按回车 选择第三个自己配置 根据需求选择 回车 选择自己需要的版本 出现这个 一直按回车大约5下或者6下 创建完毕 结束 感谢观看

Spring 中的AOP 以及与 AspectJ AOP 的区别

AOP到底是什么,有什么作用: AOP(Aspect-Oriented Programming,面向切面编程): 能够将那些与业务无关,却为业务模块所共同调用的逻辑或责任(例如事务处理、日志管理、权限控制等&…

【EAI 024】RoboVQA: Multimodal Long-Horizon Reasoning for Robotics

Paper Card 论文标题:RoboVQA: Multimodal Long-Horizon Reasoning for Robotics 论文作者:Pierre Sermanet, Tianli Ding, Jeffrey Zhao, et.al. 作者单位:Stanford University, UC Berkeley, Meta 论文原文:https://arxiv.org/a…

【Linux】部署单机项目(自动化启动)---(图文并茂详细讲解)

目录 一 准备工作 1.1 连接服务器拷贝文件 1.2 解压 二 JDK安装 2.1 配置坏境变量 2.2 查看版本 三 Tomcat(自启动) 3.1 复制启动命令的位置 3.2 添加命令相关配置文件 3.2.1 配置jdk及tomcat目录 3.2.2 添加优先级 3.3 设置自启动命令 3.4 开放端口 四 My…

3_怎么看原理图之协议类接口之I2C笔记

I2C只连接I2CSCL与I2CSDA两根线,即2线制异步串行总线。 I2CSCL与I2CSDA两根线需要上拉电阻,目的是让电平有确定的状态。 发完8bit数据后,第9个电平拉低SDA为低电平。 比如传一个数据A0x410100 0001 IIC总线有多个从机设备的通信&#xff0c…

Spring Boot 笔记 025 主界面

1.1 路由搭建 1.1.1 安装vue router npm install vue-router4 1.1.2 在src/router/index.js中创建路由器,并导出 import { createRouter, createWebHistory } from vue-router//导入组件 import LoginVue from /views/Login.vue import LayoutVue from /views/La…

Aidex移动端项目入门

运行效果 项目源码下载 若依-ruoyi-AiDex-Uniapp: 若依-Ruoyi APP 移动解决方案,基于uniappuView封装的一套基础模版,开箱即用,免费开源,一份代码多终端适配,支持H5、支付宝小程序、微信小程序、APP,实现了…

改进Yolov5目标检测与单目测距 yolo速度测量-pyqt界面-yolo添加注意力机制

当设计一个结合了 YOLOv5 目标检测、单目测距与速度测量以及 PyQt 界面的毕业设计时,需要考虑以下几个方面的具体细节: 计算机视觉、图像处理、毕业辅导、作业帮助、代码获取,私聊会回复! YOLOv5 目标检测: 首先,选择…

B树的介绍

R-B Tree 简介特性B树特性m阶B树的性质(这些性质是B树规定的) B树的搜索B树的添加B树的删除——非叶子结点 简介 R-B Tree又称为Red-Black Tree,红黑树。是一种特殊的二叉查找树,红黑树的每个节点上都有存储为表示结点的颜色&…

Camunda7.18流程引擎启动出现Table ‘camunda_platform_docker.ACT_GE_PROPERTY‘的解决方案

文章目录 1、问题描述2、原因分析3、解决方案3.1、方案一:降低mysql版本3.2、方案二:增加nullCatalogMeansCurrent参数(推荐) 4、总结 1、问题描述 需要在docker中,部署Camunda流程引擎。通过启动脚本camunda-platfor…

分布式架构(分布式ID+分布式事务)

分布式架构 分布式事务产生的场景: 跨JVM进程产生的分布式事务 单体系统访问多个数据库实例 多服务访问同一个数据库实例 CAP理论 C:一致性,指写操作后的读操作可以读取到最新的数据状态,当数据分布在多个节点上&#xff0…

flet 读取本地音频文件的信息,歌名,歌手,歌曲长度,封面

请先安装 pip install flet, tinytag 组件 tinytag 是用来读取音频文件的信息的 测试用最好找一个有封面的音频的文件, 我是windows电脑,打开预览模式,选中文件时候能够右边显示图片, 如下,我电脑上某个音频文件的封面 import flet as ft from tinytag import TinyTag import…

自动驾驶---行业发展及就业环境杂谈

进入21世纪以来,自动驾驶行业有着飞速的发展,自动驾驶技术(L2---L3)也逐渐落地量产到寻常百姓家。虽然最早期量产FSD的特斯拉有着深厚的技术积累,但是进入2010年以后,国内的公司也逐渐发展起来自己的自动驾…

YOLOv5算法进阶改进(18)— 引入动态蛇形卷积DSConv(ICCV2023 | 用于管状结构分割)

前言:Hello大家好,我是小哥谈。动态蛇形卷积(Dynamic Snake Convolution,简称DSConv)是一种用于图像处理和计算机视觉任务的卷积神经网络(CNN)操作。它是在传统的卷积操作基础上引入了动态蛇形路径的概念,以更好地捕捉图像中的细节和边缘信息。传统的卷积操作是在固定的…

读书笔记-增强型分析:AI驱动的数据分析、业务决策与案例实践

目录 前言 运用人工智能技术,可以使人类社会变得更美好。人们总是期待产品更适合、服务更贴心、生活更便利。在实践中,技术给企业赋能,企业通过优质的产品和服务满足社会,提升人类福祉。很多金融企业已经开始尝试向潜在客户推送…

Uniapp小程序开发-底部tabbar的开发思路

文章目录 前言一、uniapp 实现 tabbar二、图标使用网络图片后端返回tabbar信息uniapp方式中的setTabBarItem 总结 前言 记录uniapp 开发小程序的底部tabbar ,这里讨论的不是自定义tabbar的情况。而是使用wx.setTabBarItem(Object object) 这个api的情况。关于custo…

【Linux进程】进程状态---进程僵尸与孤儿

📙 作者简介 :RO-BERRY 📗 学习方向:致力于C、C、数据结构、TCP/IP、数据库等等一系列知识 📒 日后方向 : 偏向于CPP开发以及大数据方向,欢迎各位关注,谢谢各位的支持 目录 1.进程排队2.进程状态…