Android 内存优化内存泄漏处理

news2024/10/6 6:01:24

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

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

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

匿名内部类/非静态内部类,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() {
            @Override
            public void run() {

            }
        }).start();
    }
}

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

解决方案:

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

public class TestActivity {
    Runnable runnable1

  public static void main(String[] args) {
        
     runnable1 = new MyRunnable()

		new Thread(runnable1).start();
    }

//创建一个静态内部类
private static class MyRunnable implements Runnable{
 @Override
 public 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;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        button = new Button(this);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public 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.coloradmin.cn/o/1469480.html

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

相关文章

《艾尔登法环 黄金树幽影》是什么?Mac电脑怎么玩《艾尔登法环》艾尔登法环下载

全体起立,《艾尔登法环 》最新DLC《黄金树幽影》将在6月21日发布,steam售价198元,现在就可以预订了。宫崎英高在接受FAMI通的采访时表示,新DLC的体量远超《黑暗之魂》和《血源诅咒》资料片。好家伙,别人是把DLC续作&am…

28V270V航空交直流线缆:满足飞机对高质量电气连接的需求

28V/270V航空交直流线缆:航空业的“神经系统” 在现代航空业中,无论是飞机、直升机还是其他飞行器,都离不开一种重要的设备,那就是航空28V/270V航空交直流线缆。航空28V/270V航空交直流线缆是飞行器上的电气系统的重要组成部分&am…

【操作系统】

计算机操作系统 计算机是如何让用户得到好的体验什么是操作系统(OS)操作系统如何管理 计算机是如何让用户得到好的体验 计算机系统是由计算机硬件和软件组成的。用户使用计算机,比如在文本文件填写内容,通过邮箱发送邮件&#xf…

RabbitMq:什么是RabbitMq? ①

一、RabbitMq定位 RabbitMq是一个基于消息订阅发布的一款消息中间件。 二、技术原理 核心概念 server:又称broker,接受客户端连接,实现AMQP实体服务。缓存代理,Kafka集群中的一台或多台服务器统称broker.connection:…

Python中回调函数的理解与应用

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站零基础入门的AI学习网站~。 目录 前言 回调函数的概念 回调函数的基本用法 回调函数的实现方式 1 使用函数 2 使用类方法 3 使用类实…

Web性能优化-详细讲解与实用方法-MDN文档学习笔记

Web性能优化 查看更多学习笔记:GitHub:LoveEmiliaForever MDN中文官网 性能优良的网站能够提高访问者留存和用户满意度,减少客户端和服务器之间传输的数据量可降低各方的成本 不同的业务目标和用户需求需要不同的性能度量,要提高…

pthread_cond_timedwait()函数

绝对时间:相对于1970年1月1日0时0分0秒 相对时间:相对于当前时间,如sleep(3);相对于当前,过3s.

mac下使用jadx反编译工具

直接执行步骤: 1.创建 jadx目录 mkdir jadx2.将存储库克隆到目录 git clone https://github.com/skylot/jadx.git 3. 进入 jadx目录 cd jadx 4.执行编译 等待片刻 ./gradlew dist出现这个就代表安装好了。 5.最后找到 jadx-gui 可执行文件,双击两下…

解决easyExcel模板填充时转义字符\{xxx\}失效

正常我们在使用easyExcel进行模板填充时,定义的变量会填充好对应的实际数据,未定义的变量会被清空,但是如果这个未定义的变量其实是模板的一部分,那么清空了就出错了。 在这张图里,上面的是模板填充后导出的文件&…

【Linux基础】vim、常用指令、组管理和组权限

Linux基础 1、目录结构2、vi和vim3、常用指令运行级别找回密码帮助指令时间日期指令搜索查找文件目录操作磁盘管理指令压缩和解压缩 4、组管理和组权限用户操作指令权限 1、目录结构 Linux的文件系统是采用级层式的树状目录结构,在此结构中的最上层是根目录“/”&a…

《Docker 简易速速上手小册》第7章 高级容器管理(2024 最新版)

文章目录 7.1 容器监控与日志7.1.1 重点基础知识7.1.2 重点案例:监控 Flask 应用7.1.3 拓展案例 1:使用 ELK Stack 收集和分析日志7.1.4 拓展案例 2:使用集成监控工具 7.2 性能调优与资源限制7.2.1 重点基础知识7.2.2 重点案例:Fl…

爬取链家二手房房价数据存入mongodb并进行分析

实验目的 1.使用python将爬虫数据存入mongodb; 2.使用python读取mongodb数据并进行可视化分析。 实验原理 MongoDB是文档数据库,采用BSON的结构来存储数据。在文档中可嵌套其他文档类型,使得MongoDB具有很强的数据描述能力。本节案例使用的…

Flutter Slider自定义滑块样式 Slider的label标签框常显示

1、自定义Slider滑块样式 Flutter Slider控件的滑块系统样式是一个圆点,thumbShape默认样式是RoundSliderThumbShape,如果想要使用其它的样式就需要自定义一下thumbShape; 例如需要一个上图样式的(圆点半透明圆形边框&#xff09…

Springboot+vue的社区医疗综合服务平台(有报告)。Javaee项目,springboot vue前后端分离项目

演示视频: Springbootvue的社区医疗综合服务平台(有报告)。Javaee项目,springboot vue前后端分离项目 项目介绍: 本文设计了一个基于Springbootvue的前后端分离的社区医疗综合服务平台,采用M(m…

Debezium发布历史149

原文地址: https://debezium.io/blog/2023/06/21/debezium-2-3-final-released/ 欢迎关注留言,我是收集整理小能手,工具翻译,仅供参考,笔芯笔芯. Debezium 2.3.0.Final Released June 21, 2023 by Chris Cranford re…

平衡,才是世界生生不息的真谛

凤凰涅槃,浴火重生。这句话是很有哲理的,可以运用到命运中。而对于命运,以中为最好,即是平衡。然而,每一个人,都是要经历命运的锤炼,无论怎样锤炼,都要保持一颗善良的心,…

【黑马程序员】1、TypeScript介绍_黑马程序员前端TypeScript教程,TypeScript零基础入门到实战全套教程

课程地址:【黑马程序员前端TypeScript教程,TypeScript零基础入门到实战全套教程】 https://www.bilibili.com/video/BV14Z4y1u7pi/?share_sourcecopy_web&vd_sourceb1cb921b73fe3808550eaf2224d1c155 目录 1、TypeScript介绍 1.1 TypeScript是什…

2024年最新汉化版电脑数据恢复软件EasyRecovery易恢复14

一、功能特点 2024 EasyRecovery易恢复软件,是一款广受欢迎的数据恢复工具。其全面的功能特点让它在数据恢复领域占有一席之地。 EasyRecovery-mac最新版本下载:https://wm.makeding.com/iclk/?zoneid50201 EasyRecovery-win最新版本下载:https://wm.makeding.c…

MATLAB环境下基于粒子群优化算法和离散小波变换的心电信号降噪

由于现实环境的复杂性以及信号获取设备的非理想特性等原因,导致人们在获得信号的过程中会引入各种各样的噪声成分,这不但会使得信号质量达不到实际要求,而且会掩盖信号中的重要细节。这也就要求我们在对数字信号进行具体地分析处理之前&#…

第九篇【传奇开心果系列】python文本和语音相互转换库技术点案例示例:SpeechRecognitio库开发会议记录和转录工具经典案例

传奇开心果博文系列 系列博文目录python文本和语音相互转换库技术点案例示例系列 博文目录前言一、雏形示例代码二、扩展思路介绍三、SpeechRecognition库多种语音识别引擎支持示例代码四、SpeechRecognition库实时语音转录示例代码五、SpeechRecognitio库转录文本中提取关键词…