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://xiahunao.cn/news/2807439.html

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

相关文章

数据结构与算法相关题解20240225

数据结构与算法相关题解20240225 一、58. 最后一个单词的长度二、48. 旋转图像三、69. x 的平方根四、50. Pow(x, n) 一、58. 最后一个单词的长度 简单 给你一个字符串 s,由若干单词组成,单词前后用一些空格字符隔开。返回字符串中 最后一个 单词的长度…

开源世界的学术问题

自由软件基金会是1983年成立的,到现在是41年。正好很有意思的是,在去年还有一篇文章(CSDN 的翻译),专门在质疑说成立 40 年的自由软件基金会是不是已经快不行了,所以我们会用这个标题叫做兴衰发展历程来介绍…

无人机精准定位技术,GPS差分技术基础,RTK原理技术详解

差分GPS的基本原理 差分GPS(Differential GPS,简称DGPS)的基本原理是利用一个或多个已知精确坐标的基准站,与用户(移动站)同时接收相同的GPS卫星信号。由于GPS定位时会受到诸如卫星星历误差、卫星钟差、大…

创建者模式(Builder Pattern):构造复杂对象的通用解决方案

文章目录 **一、技术背景与应用场景****为何使用创建者模式?****典型应用场景包括但不限于:** **二、创建者模式定义与结构****三、使用步骤举例**四、优缺点分析总结 一、技术背景与应用场景 创建者模式是一种对象创建型设计模式,它通过将复…

修复Microsoft Edge WebView2无法安装的问题

修复Microsoft Edge WebView2无法安装的问题 场景解决方案 场景 系统:win11 电脑:联想14 前提:使用Geek Uninstaller强制删除了Microsoft Edge WebView2 同时下载了clash verge。 发现根本无法运行(点击了无任何反应且图标颜色…

电影《热辣滚烫》观后感

过完年,回来的时候,上周看了这部电影《热辣滚烫》,是贾玲自导自演的一部电影,个人感觉还是非常好的,偏向小人物,写实风格。 (1)电影相关评价 但是你说这部电影有多立志&#xff0c…

vue2和vue3对比(语法层面)

阅读文章你将收获: 1 了解不使用组件化工具时,vue在html是如何使用的 2 知道vue2的生命周期函数有哪些 3 知道如何在组件化开发中使用vue 4 大致了解了vue2和vue3在使用上什么不同 最后:vue2和vue3除了下面我列出的有差异化的地方&…

勇宝趣学JavaScript第二章(解构赋值)

在ES6中,我们经常使用到解构赋值这个知识点,今天我们就来好好讲讲这一小部分知识点。咱们争取这回一次性讲明白。 今天是元宵节,祝大家节日快乐,只有我自己还在无聊的码字。 给我点个赞吧,嘿嘿!&#xff01…

项目解决方案:视频监控AI智能分析和识别系统设计方案

目 录 一、需求分析 二、系统设计原则 2.1、先进性与适用性 2.2、经济性与实用性 2.3、可靠性与安全性 2.4、开放性 2.5、可扩充性 2.6、追求最优化的系统设备配置 三、系统架构 3.1软件架构 3.2系统说明 四、拉流模块服务器配置 一、需求分析 本系统设计…

力扣用例题:2的幂

此题的解题方法在于根据用例调整代码 bool isPowerOfTwo(int n) {if(n1){return true;}if(n<0){return false;}while(n>2){if(n%21){return false;}nn/2; }if(n1){return false;}return true;}

[LWC] Components Communication

目录 Overview ​Summary Sample Code 1. Parent -> Child - Public Setter / Property / Function a. Public Property b. Public getters and setters c. Public Methods 2. Child -> Parent - Custom Event 3. Unrelated Components - LMS (Lightning Message…

Mysql--索引分类

Mysql--索引分类 1. 索引分类2. 聚集索引&二级索引 1. 索引分类 在MySQL数据库&#xff0c;将索引的具体类型主要分为以下几类&#xff1a;主键索引、唯一索引、常规索引、全文索引。 2. 聚集索引&二级索引 而在在InnoDB存储引擎中&#xff0c;根据索引的存储形式&am…

计算机网络-网络互联

文章目录 网络互联网络互联方法LAN-LAN&#xff1a;网桥及其互连原理使用网桥实现LAN-LAN使用交换机扩展局域网使用路由器连接局域网 LAN-WANWAN-WAN路由选择算法非自适应路由选择算法自适应路由选择算法广播路由选择算法&#xff1a;分层路由选择算法 网络互联 网络互联是指利…

【云原生】Docker consul的容器服务更新与发现

目录 什么是服务注册与发现 什么是consul consul提供的一些关键特性&#xff1a; consul 部署 consul服务器 1. 建立 Consul 服务 设置代理&#xff0c;在后台启动 consul 服务端 2. 查看集群信息 查看members状态 查看集群状态 3. 通过 http api 获取集群信息 regi…

【leetcode热题】填充每个节点的下一个右侧节点指针 II

给定一个二叉树&#xff1a; struct Node {int val;Node *left;Node *right;Node *next; } 填充它的每个 next 指针&#xff0c;让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点&#xff0c;则将 next 指针设置为 NULL 。 初始状态下&#xff0c;所有 next 指针都…

10-pytorch-完整模型训练

b站小土堆pytorch教程学习笔记 一、从零开始构建自己的神经网络 1.模型构建 #准备数据集 import torch import torchvision from torch.utils.tensorboard import SummaryWriterfrom model import * from torch.utils.data import DataLoadertrain_datatorchvision.datasets.…

3.openEuler物理存储及逻辑卷管理(一):磁盘存储挂载与使用

openEuler OECA认证辅导,标红的文字为学习重点和考点。 如果需要做实验,建议下载麒麟信安、银河麒麟、统信等具有图形化的操作系统,其安装与openeuler基本一致。 磁盘大类: HDD, (Hard Disk Drive的缩写) : 由一个或者多个铝制或者玻璃制成的磁性碟 片,磁头,…

C#最优队列最小堆小顶堆大顶堆小根堆大根堆PriorityQueue的使用

最优队列有多种叫法&#xff0c;什么小根堆&#xff0c;大根堆&#xff0c;小顶堆&#xff0c;大顶堆。 队列分多种&#xff0c;线性队列&#xff08;简单队列&#xff09;&#xff0c;循环队列&#xff0c;最优队列等等。 最优队列&#xff0c;可以看作堆叠箱子&#xff0c;…

指定指数x 计算e^x - 1 math.expm1(x)

【小白从小学Python、C、Java】 【计算机等考500强证书考研】 【Python-数据分析】 指定指数x 计算e^x - 1 math.expm1(x) 选择题 请问执行math.expm1(0)的运行结果是&#xff1a; import math print("【执行】math.expm1(0)") print (math.expm1(0)) print("【…

linux前端部署

安装jdk 配置环境变量 刷新配置文件 source profile source /etc/profile tomcat 解压文件 进去文件启动tomcat 开放tomcat的端口号 访问 curl localhsot:8080 改配置文件 改IP,改数据库名字&#xff0c;密码&#xff0c; 安装数据库 将war包拖进去 访问http:…