美文网首页
内存优化

内存优化

作者: 差点长成一枚帅哥 | 来源:发表于2020-08-31 23:11 被阅读0次

    一、JVM内存模型与分布

    我们都知道JVM运行时的数据区域分为5大块

    image.png
    • 1.程序计数器:虚拟机字节码的行号记录器,占用内存非常小,可以不用考虑。
    • 2.虚拟机栈:这个区域描述的是java方法执行的内存模型,每个方法代表一个栈帧,方法内大部分定义的变量都是栈里面的成员,他是有生命周期的,伴随着方法执行结束而销毁。
    • 3.本地方法栈:同虚拟机栈很相似,但他是Native层的。
    • 4.堆:几乎所有对象都在这个区域产生,该区域属于线程共享区域,所以线程销毁时,需要注意对象的销毁
    • 5.方法区::主要存储虚拟机加载的类信息,常量,静态变量,及时编译器编译后的代码等数据。

    二、内存限制

    android是基于Linux系统的,android中的进程分为两种:

    • 1.native进程:采用C/C++实现,不包含dalvik实例的linux进程,/system/bin/目录下面的程序文件运行后都是以native进程形式存在的
    • 2.java进程:实例化了dalvik虚拟机实例的linux进程,进程的入口main函数为java函数。dalvik虚拟机实例的宿主进程是fork()系统调用创建的linux进程,所以每一个android上的java进程实际上就是一个linux进程,只是进程中多了一个dalvik虚拟机实例
      我们知道,操作系统对进程的内存是有限制的,而且操作系统对dalvik虚拟机自身的堆内存大小也是有限制的。可以通过如下命令查看限制大小:
    adb shell getprop | grep dalvik.vm.heapgrowthlimit
    

    可以在Androidmanifest文件中application节点加入android:largeHeap=“true”来增加其dalvik虚拟机中堆的大小
    我们常说的堆大小其实是包涵两部分的,一是java的堆,而是native的堆,java堆中主要是一下java对象,由 C/C++申请的内存空间则在native堆中,也有一些对象需要结合native和java堆共同完成,比如bitmap,bitmap分为bitmap对象和其中存储的像素值,对象分配在java堆,而存储的像素值则根据版本不同存储的位置也不同,api 11 - api 25是存储在java堆中的,其他版本是存储在native堆中的

    三、内存泄漏场景

    1.静态引用

    静态对象非法持有Activity上下文

    2.匿名内部类,或非静态内部类

    Handler,AsyncTask,TimerTask等,一般在处理多线程任务的时候

    3.监听器

    在Activity OnResume里面registListener,在OnPause一定要记得unregistListener

    4.资源对象

    BraodcastReceiver, ContentObserver,File,Cursor,Stream,Bitmap,Socket等资源,使用后未关闭会导致内存泄漏。这些对象JVM中有的只保存引用,而真实的数据存在JVM之外的内存,所以并非对象制为null即可,必须 调用 recycle, release, close等方法,清空内存。

    4.WebView

    在Activity的onDestory中调用 WebView的 clearHistory, clearView,destroy方法即可。

    四、如何排查以及修复

    1.LeakCanary
    2.Android Studio 3.0 的 Android Profiler 分析器

    五、如何进一步进行优化

    • 1.资源优化:

    1.shape代替图片资源
    2.部分png图改jpg图,比如启动页
    3.gradle配置shrinkResources属性,删除无效资源

    • 2.代码优化

    1.删除冗余代码,减少编译带来的内存开销
    2.第三方库so包的缩小, 能满足需求的情况下,尽量实用阉割版

    相关文章

      网友评论

          本文标题:内存优化

          本文链接:https://www.haomeiwen.com/subject/qmrbdktx.html