文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

android内存泄露:1、LeakCanarys内存泄漏检测库、非静态的内部类错误使用

2022-06-06 13:54

关注

一、前言

今天来复习一下有关内存泄露的知识,一个是把之前笔记整理一下,如有一些工具版本更新会写一些当下的使用介绍。另外会参考网上比较好的博文进行修正改进一些知识点

二、内存泄露、内存溢出、内存抖动

首先我们必须对内存泄露有一个最简单的了解,就是一些对象有着有限的生命周期,当这些对象所要做的事情完成了,我们希望他们会被回收掉。但是如果有一系列对象对这个对象的引用,那么在我们期望这个对象生命周期结束的时候被GC回收的时候,它是不会被回收的,它还会占用内存,导致堆内存直升不降,这就造成了内存泄露

内存泄漏:
 指对象不再使用,本该被回收,却因为有其他正在使用的对象持有该对象的引用,而无法被GC回收,它占用内存,导致堆内存直升不降的情况。

内存溢出:我们可以把app的堆内存空间想成了一个杯子,内存就是里面的水。当用户重复这个操作或者有多个不同Activity内存泄漏时,app运行一段时间堆内存超过系统规定的最大值 heapSize,杯子满了就会发生内存溢出(OOM)

内存抖动:是因为短时间内大量的对象被创建然后又被马上释放,瞬间产生大量的对象会严重占用内存区域,这块内存区域就是Young Generiation内存区域。当达到它的阀值,剩余空间不够的时候,就会触发GC(垃圾回收机制),这样刚产生的对象很快就被回收,每一次分配对象占用很少内存,但是它们叠加在一起就会造成Heap(堆内存)的压力,从而触发更多其他类型的GC,这个操作有可能会影响到帧率,并使得用户感知到性能问题。

内存溢出,内存抖动,内存泄漏这三者中这里面最严重的现象还是OOM也就是内存溢出,在开发过程中提到内存首先会想到内存溢出OOM,内存泄漏,然后才是内存抖动,内存抖动三者中严重程度比较轻。

内存溢出就是分配的内存不足以让你做有些操作,就是堆内存上有些内存没有被释放从而它会失去控制,造成程序使用的内存越来越少,导致系统运行速度减慢,严重程度下OOM,会造成整个程序的崩溃,所以为了提高APP的质量提高用户体验,我们必须避免与解决OOM。

三、LeakCanary 内存泄漏检测库-使用介绍

内存泄露分析工具:使用 square公司的 LeakCanary 分析activity的内存泄露

1、github上搜索 LeakCanary 工具

可在 github上搜索 LeakCanary 工具,可以看到 leakcanary 的源码:https://github.com/square/leakcanary

LeakCanary is a memory leak detection library for Android.    LeakCanary是一个用于Android的内存泄漏检测库。

2、集成方式

集成方式,点击链接:https://square.github.io/leakcanary/  ,如下图,

集成,目前最新版本 2.2 ,只需在 build.gradle 添加如下依赖:

    // debug Implementation because LeakCanary should only run in debug builds.
    // 调试实现,因为LeakCanary只应在调试生成中运行。
    debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.2'

That’s it, there is no code change needed!   就这样,不需要修改代码!

当然上面还有更新的提示:

To upgrade from LeakCanary 1.6, follow the upgrade guide.  要从LeakCanary 1.6升级,请遵循升级指南。

3、案例:非静态的内部类错误使用,导致 Activity内存泄露 

下面我们来看一下案例:

步骤1:新建一个 Module(模块/组件)

我们可以在项目上,新建一个Module:File--->New--->New Module

然后一直默认。。。,完成如下:

步骤2:写主界面 MainActivity、布局activity_main

布局activity_main



    

复习一下快捷键:option + enter

option + enter,会在 MainActivity 里面,自动生成方法:  public void innerClass(View view) { }

主界面 MainActivity


package com.yyh.testleakdemo;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
    public void innerClass(View view) {
        startActivity( new Intent(MainActivity.this, InnerClassActivity.class));
    }
}
步骤3:写业务逻辑:InnerClassActivity

子线程执行耗时操作


package com.yyh.testleakdemo;
import android.os.Bundle;
import android.os.SystemClock;
import androidx.appcompat.app.AppCompatActivity;

public class InnerClassActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_inner_class);
        
        new Thread(new Runnable() {
            @Override
            public void run() {
                //模拟耗时操作
                SystemClock.sleep(100*1000);
            }
        }).start();
    }
}
  4、效果展示

在夜神模拟器上,运行Module模块:testleakdemo

点击 Button跳转到一个 Activity,执行耗时线程操作,然后点击返回按钮 Activity退出,

InnerClassActivity 里面的耗时线程操作还没执行完,然后我们可以看到 LeakCanary 工具有内存泄露的相关提示

5、分析小结、解决方式

分析小结

在Activity中启动子线程,子线程执行耗时操作,但是当Activity退出的时候,如果线程的任务还没执行完,那么该线程对象就不会死掉,该线程由于是Activity的内部对象,因此对外部类(Activity)有一个隐式的强引用,从而导致Activity也无法被GC回收掉,最后导致Activity一定时间的泄露。

解决方式

解决该泄露的方式:就是我们应该谨慎在Activity中开辟耗时的子线程,如果使用了那么也应该保证当Activity销毁的时候,将线程的任务退出。或者我们可以自定义一个静态的类继承Thread,然后再使用。因为只有非静态的内部类对象才会对外部类有隐式的强引用。

四、其他

square公司,对我们 android来说,是一个大名鼎鼎的公司,它开源了相当多的开源框架。

比如说:LeakCanary(内存泄漏检测库)、OKHttp(网络请求库)、Picasso(图片库)、Retrofit(网络请求接口的封装)

square开源官网:https://square.github.io/#android

然后写博文的时候,偶然看到这篇博文,这哥们挺逗的


阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-移动开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯