在Android 使用的是davilk虚拟机 它和java虚拟机 类似 但是它是使用基于寄存器的 java基于栈的
davilk虚拟机的 编译出来的文件也不同 它是拥有 一个dex文件有多个class 而java虚拟机是 一个文件对应一个class
davilk虚拟机 是先编译成class 文件 然后通过 dx 工具在打包成一个dex文件。
一个android app 就是一个davilk虚拟机 它是由zygote进程中davilk虚拟机 复制过来的。
adb shell cat /system/build.prop 查看系统设置最大 java object heap 的大小
在Android启动中 davilk虚拟机 java object heap size navtive heap size
java object heap 是有限制的 可以通过 root adb shell cat /system/build.prop 来查看
navtive heap size 大概率是没有限制
adb shell cat /proc/pid/oom_adj 查看当前app所处于的进程
android 的 前台进程 0 可见进程 后台进程 11 服务5 服务8 空进程 -11--16
如果两个进程都是后台进程 11 那么 谁占用的内存大就回收谁。 所以内存回收非常重要
如何 查看 adb shell cat /proc/pid/oom_adj
OOM问题:
内存泄漏: 当应用周期内 不再使用的对象被GC ROOTS引用 导致不能回收 会使实际可用的java 堆内存变小 就会发生内存泄漏
内存泄漏 超过单个应用最大的使用内存,超出这个值就会OOM
OOM 有很多中 不一定是 超过最大使用堆内存
OOM
1. JAVA堆内存溢出
2. 无足够的连续空间
3. FD数量超过限制
4. 线程数量超过限制
5. 虚拟内存不足
我们可以使用 adb shell dumpsys meminfo --package 包名
如果多个设备 adb -s xxx shell
从下载hprof后 要通过Android sdk 中platm-tools hprof-conv.exe 来转换成MAT所需要的文件
out-coming 是 该对象中引用了谁 in-comeing 是 谁引用了该对象
- 资源性的泄漏 比如database中
- 注册对象未注销 比如 广播 eventBus
- 类的静态变量持有大数据对象。
- 单例模式造成的泄漏 比如Context 传入了Activity
- 非静态内部类的静态实例
- Handler的零时性泄漏
- 容器中的对象没有clear 并且设置null
- webView 需要使用aidl进程通信
地图中 BitMapFactory.Option 参数 中有个参数 inJustDecodeBounds=true 可以不加载图片不分配内存,但会返回图片的宽度和高度。 然后 通过samleSize来缩放图片比例
1个像素 有一个参数Config ALPHA(1) 是占1个字节(byte) RGB_565是占2个字节(byte)
ARGB_888是占4个字节 ARGB_F16占 8个字节(byte) 、
在Android图片中占用的内存大小是
那么大小就是
1920x1080像素 占多少内存 1920x1080x4x((设备密度/图片所在文件夹的密度)^2)/1024= KB
mdpi hdpi xdpi xxdpi xxxdpi 160 240 320 480 560
但是在文件和网络上加载的图片就没有1920x1080x4/1024=kb
8bit(位)=1Byte(字节)
1024Byte(字节)=1KB
1024KB=1MB
1024MB=1GB
1024GB=1TB
Bitmap的内存模型 Android 3.0-4.4 bitMap对象保存在java Heap 像素数据保存在 native Heap Android 5.0-7.0 bitmap对象保存在java Heap 像素数据保证在 java Heap Android 8.0 bimap对象保存在java Heap 像素数据保存在 native Heap
内存优化整体思想:
- 设备分级:
- BitMap优化 统一图片库 线上 线下监控
- glide图片加载库
LeakCanary 内存检测工具
两部分
1.找出泄漏的嫌疑的对象。原理
2.确诊:haha开源库 利用这个可达性分析
LeakCanary的原理 在ActivityThread中的bindAppcalition方法 ContentProvider.onCreate 会比Appcaliton.onCreate 更早执行
LeakCanary检测Activity退出的原理
ActivityLifecycleCallbacks 可以监听Activity的生命周期 Fragment的生命周期
JAVA四种引用和引用队列ReferenceQueue的关系
RefereQueue 引用队列 就是存放引用的队列
作用:当作用于Reference对象所引用的对象被GC回收的时候,该Reference对象将会被加入引用队列的末尾
当弱引用 WeakReference weakReference=new WeakReference(obj,referenceQueue)
leakcanary watch 一个对象5s 加入观察列表