网站首页 > 博客文章 正文
1.前言
- 内存调优 是体现Android性能主要部分之一。
- 内存调优 中包含三种比较常见的场景,分别是内存泄漏、内存溢出、内存抖动。 内存泄漏:指某块内存在使用完毕之后,还被其他对象引用着,导致GC回收不了。(生命周期长的对象引用生命周期短的对象) 内存溢出:指应用内存超出Android系统赋予给每一个应用最大容量的限制。(OutOfMemory) 内存溢出:指在短时间内有大量的对象被创建或者被回收的现象。(循环种大量创建对象、回收内存GC)
- 今天主要分享前2种场景。
- 在分享前,先了解或者复习以下的技术点,以便更好理解后续内容:
1.1 内存
JAVA是在JVM所虚拟出的内存环境中运行的,主要的内存区:堆、栈和方法区。
栈(stack):是简单的数据结构与变量,程序运行时系统自动分配,使用完毕后自动释放。优点:速度快。
堆(heap):用于存放由new创建的对象和数组。在堆中分配的内存,一方面由java虚拟机自动垃圾回收器来管理,另一方面还需要程序员提供修养,防止内存泄露问题。
方法区(method):又叫静态区,跟堆一样,被所有的线程共享。方法区包含所有的class和static变量。
1.2 Java GC
GC可以自动清理堆中不在使用(不在有对象持有该对象的引用)的对象。
在JAVA中对象如果再没有引用指向该对象,那么该对象就无从处理或调用该对象,这样的对象称为不可到达(unreachable)。垃圾回收用于释放不可到达的对象所占据的内存。
对android来说,内存使用尤为吃紧,最开始的app进程最大分配才8M的内存,渐渐增加到16M、32M、64M,但是和服务端相比还是很渺小的。如果对象回收不及时,很容易出现OOM错误。
- 文章中实例 linhaojian的Github
2.内存泄漏
2.1 场景
- 罗列一些会导致内存泄漏的场景,如下: 单例中引用Activity对象; 静态(static)变量中持有生命周期短的对象; 匿名内部类中执行耗时任务(Handler); 非静态内部类(MyThread); 异步处理耗时任务,在finish时未终止(new Thread); 资源对象未关闭或者释放(Cursor、Bitmap);
2.2 处理
- 内存泄漏 的 2 种检测方式:Android Profile & LeakCanary。
- 通过异步处理耗时任务的例子,讲解 2 种检测方式,代码如下:
public class LeakCanaryActivity extends AppCompatActivity {
private Button btn_leakcanary;
private Leak leak;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.leakcanary);
leak = new Leak();
btn_leakcanary = findViewById(R.id.btn_leakcanary);
btn_leakcanary.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//开启内存泄漏
leak.staticRun();
}
});
}
class Leak {
public Leak(){
}
public void staticRun(){
new Thread(){
@Override
public void run() {
while(true){
Log.i("linhaojian","内存泄漏中....."+Thread.currentThread().getName());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
}
}
2.2.1 Android Profile
- Android Profile 是Android Studio自带的检测性能相关的功能,通过Android Profile如何分析上述例子泄露的问题;
- 1.第一次运行上述例子 & finish上述Activity,然后点击回收功能,看看Android Profile的Memory变化:
- 2.继续执行第一步的操作,结果如下:
从上述图一,可以发现LeakCanaryActivity类 finish & GC 之后,都是还是存在于内存中,说明已经造成了内存泄漏。
从上述图二,可以发现重复执行第一步的操作之后,在Allocation中,LeakCanaryActivity对象在内存中造成了 2 个对象未被回收。
2.2.2 LeakCanary
- LeakCanary 是由Square公司维护的一个内存泄漏检测框架库。
- 引入
dependencies {
//...
debugImplementation 'com.squareup.leakcanary:leakcanary-android:1.6.2'
releaseImplementation 'com.squareup.leakcanary:leakcanary-android-no-op:1.6.2'
// Optional, if you use support library fragments:
debugImplementation 'com.squareup.leakcanary:leakcanary-support-fragment:1.6.2'
}
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
//初始化
if(!LeakCanary.isInAnalyzerProcess(this)){
LeakCanary.install(this);
}
}
}
- 使用
- 运行上述的例子,看看手机上的通知栏变化:
- 点击图上的ReportFragment leaked,查看泄漏的相关信息,如下图:
- 展开红色框选型,就能详细查看具体内存泄漏的位置:
内存泄漏发生的类:LeakCanaryActivity中内部类Leak;
内存泄漏发生的线程:staticRun函数中的Thread(name:Thread-2);
3.内存溢出
3.1 场景
- 罗列一些会导致内存溢出的场景,如下: 大量使用Bitmap; 内存中存在大量的强引用对象;
3.2 处理
1.适合选择不同的引用方式创建对象(强、软、弱、虚);
2.在必要时块合理的按模划分**多进程(android:process=":xxx")**开发,分散内存占用;
3.内存对象的重复利用;
4.优化布局层次,重用,需要时加载ViewStub,减少内存消耗;
4.总结
- 到此,内存调优 介绍完毕。
- 如果喜欢我的分享,可以点击 关注 或者 赞,你们支持是我分享的最大动力 。
- linhaojian的Github
欢迎关注linhaojian_CSDN博客或者linhaojian_简书!
不定期分享关于安卓开发的干货。
写技术文章初心
技术知识积累 技术知识巩固 技术知识分享 技术知识交流
如果本文对你有帮助,别忘记给我个3连 ,点赞,转发,评论,
咱们下期见!学习更多JAVA知识与技巧,关注与私信博主(666)
猜你喜欢
- 2024-11-15 IntelliJ IDEA 2021.1正式发布!快来看看又有哪些神仙功能加入
- 2024-11-15 HarmonyOS开发:超详细介绍如何开源静态共享包,实现远程依赖
- 2024-11-15 微星武士66游戏本详细评测:亲民价位段的上品之作
- 2024-11-15 创建属于自己的第一个flutter项目
- 2024-11-15 Jetpack系列:应用内导航的正确使用方法
- 2024-11-15 Meta Quest App开发、调试、分析、优化工具汇总推荐
- 2024-11-15 在线等,我的 adb 找不到了(adb工具找不到设备)
- 2024-11-15 社交软件开发5-客户端开发-android和ios验证登陆
- 2024-11-15 Android开发拾遗:如何减少重组(android原生开发)
- 2024-11-15 Android内存优化大盘点(android如何节省内存优化)
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- powershellfor (55)
- messagesource (56)
- aspose.pdf破解版 (56)
- promise.race (63)
- 2019cad序列号和密钥激活码 (62)
- window.performance (66)
- qt删除文件夹 (72)
- mysqlcaching_sha2_password (64)
- ubuntu升级gcc (58)
- nacos启动失败 (64)
- ssh-add (70)
- jwt漏洞 (58)
- macos14下载 (58)
- yarnnode (62)
- abstractqueuedsynchronizer (64)
- source~/.bashrc没有那个文件或目录 (65)
- springboot整合activiti工作流 (70)
- jmeter插件下载 (61)
- 抓包分析 (60)
- idea创建mavenweb项目 (65)
- vue回到顶部 (57)
- qcombobox样式表 (68)
- vue数组concat (56)
- tomcatundertow (58)
- pastemac (61)
本文暂时没有评论,来添加一个吧(●'◡'●)