Android GC是个啥

521 阅读3分钟

问:

  • GC的含义
  • Android GC的历史?
  • 强、软、弱、虚引用是什么?
  • 内存抖动是什么?
  • 作为一个程序员该做些什么?

GC的含义

GC指垃圾回收(Garbage Collection),是一些语言管理内存的方式。程序员不需要管理内存,程序员运行环境(虚拟机)会做垃圾回收的工作,在合适的时间释放不需要的内存。

GC Rooot

正确的释放内存就是GC的责任,GC的原则是保证正确性的前提下,尽可能的提升性能。于是就使用了GC Root 的机制,GC认为 GC Root 所引用的对象是程序后面可能会被用到的,所以不会释放;没有被 GC Root 直接或者间接引用的对象,后面一定不会被用到,可以释放掉。

Android GC的历史?

Android4.4

1、Dalvik 虚拟机 ,HTC G1是第一款Android设备。

2、Dalvik 回收原理

使用了单独的进程来分配内存,内存分配效率低。在整个堆中寻找适合分配的内存,如果当前堆中没有合适的分配的内存,就会促发GC流程,把没有被GC Root引用的对象给回收掉。

3、Dalvik 回收问题

如果回收过后依然没有足够的空间,可能会导致2个问题:

1) 增大堆体积,抛出OutOfMemoryError(堆体积已经最大)

2) Dalvik的问题:碎片化。如果有200M的空间,但都是200个1M的碎片空间,此时想要分配2M的空间,则会抛出OOM的错误

Android 5.0~7.0

1、抛弃Dalvik,引入ART

2、引入分代管理机制

将堆分成新生代(Young Generation)和老年代(Old Generation),对应的GC也分为两种:1)Minor GC: 针对新生代的垃圾回收;2)Major GC (Full GC) : 针对整个堆的垃圾回收。

Android 8.0~9.0

1、ART 引入了 Bump Allocator 的机制来分配内存

2、移除分代管理机制

Android 10

加回了分代管理机制

强、软、弱、虚引用是什么?

  • 强引用(StrongReference): JVM 宁可抛出 OOM ,也不会让 GC 回收具有强引用的对象

  • 软引用(SoftReference): 只有在内存空间不足时,才会被回的对象

  • 弱引用(WeakReference): 在 GC 时,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存

  • 虚引用(PhantomReference): 任何时候都可以被GC回收,当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之关联的引用队列中。程序可以通过判断引用队列中是否存在该对象的虚引用,来了解这个对象是否将要被回收。

内存抖动是什么?

这是被面试官带出来的一个词,实际的原理很简单:

如果高频的申请较大尺寸的内存,则可能导致段时间内频繁的粗发GC,造成内存的频繁申请和释放,使用Profiler查看内存使用时,看起来就是一个抖动的曲线。

image.png 如果平时的开发很关注性能,这种情况很难发生。那么在什么情况下会发生内存抖动呢?有兴趣的朋友可以尝试就是在自定义View的onDraw的方法中创建一个很大的对象去试一试。

作为一个程序员该做些什么?

伴随着ART的推出和迭代,它变得更好了,我们能做的GC优化越来越少。在native语言中,内存的申请和释放需要程序员来操作,忘记释放或者释放的时机不对都会产生问题。我们着重点关心业务,关心应用的性能就足够了。