性能优化(二)-内存优化1

112 阅读3分钟

1、内存核心指标

VSS: 虚拟耗用的内存,包含与其他进程共享的内存

RSS:实际使用的物理内存,包含与其他进程共享的内存

PSS:实际使用的物理内存,按比例包含与其他进程共享的内存

USS:实际使用的物理内存,不包含共享的内存。这个最准。

用户CPU时间 系统CPU时间 CPU时间

用户CPU时间 = 运行状态下用户空间的时间

系统CPU时间 =  运行状态下系统空间的时间。

用户CPU时间+系统CPU时间=运行时间,也就是进程时间(CPU时间)。

Java内存分配

image.png

jvm垃圾回收算法

标记清除算法

标记要清理的内存,再对标记的目标进行清理。产生大量内存碎片。 有点速度快

复制算法

内存空间一分为二,一半用来分配对象,一半空置。回收时,将存活对象复制到空置空间,内存连续。存对象的一半空间为from,另一半为to。当复制完后,from to交换一下。当eden没有满的时候,gc时,会把存活对象放到from,然后to是空的。只有from满了,from和to名字才会交换一下。

内存虽然连续,但是浪费一半空间。比标记整理的复制对象要快一些。

标记整理算法 标记过程和标记清除算法一样,存活对象往一端移动,直接清理调端外内存。以保存内存连续性。 但是大量移动对象,速度慢,没有内存碎片。

分代收集算法 分为新生代和老年代。新生代一个Eden区和两个Survivor区,它们之间的比例为(8:1:1)

image.png

新生代中分为,伊甸园, from 和to。这里主要用到复制算法。

对象分配在伊甸园区域

新生代空间不足会触发Minor GC,伊甸园和form的复制到to当中,存活年龄加1,然后from和to调换下名字。

Minor GC会短暂触发stop the world,暂停其它用户的线程,等待垃圾回收结束,用户线程才恢复运行。

对象寿命超过阈值15,会进入老年代,其实也就是对象头中的4位。当然各个垃圾回收器不一样。

大对象会直接进入老年代

当老年代空间满了的时候就会进行full GC。老年代用的是标记整理和标记清除算法。看用哪个收集器了

android kill机制

在Android的lowmemroykiller机制中,每一类别的进程会有oom_adj值的取值范围, oom_adj值越高越不重要,在系统执行低杀操作时,会从oom_adj值越高的开始杀。

期望长时间保留的后台服务,建议于UI进程分开,因为到到后台后,UI进程分到cached进程。

GCroot的几个根

内存分区的角度

1、虚拟机栈中引用对象。

2、方法区中的静态&常量引用的对象。(位于元空间

3、本地方法栈JNI的引用对象。

从程序运行的角度来说

一些在程序运行过程中始终保持存活,不死亡的对象可以作为GC Root

1、类的Class对象所引用的对象

2、存活的线程对象

leakcancary的使用

activity在执行销毁的时候 我们如何得知?

用lifecyclecallback

如何判断一个Activity无法被GC机制回收?

用弱引用看activity是否被释放。具体操作用weakhashmap,在application中的callback中。onDestory中加入,weakhashmap。在onstop中在后台时,执行gc,延时然后遍历weakhashmap,看是否activity是否被释放。