JavaAndroid

内存回收机制

2020-11-29  本文已影响0人  码农修行之路
clipboard.png

看上图,可以看出垃圾回收机制的几个区域
通过内存图可以看出,内存分为三个区域:

android系统中Gc有三种类型:
其它Gc应该注意的情况:
  1. 尽量不去显式的调用gc,减少不必要的开销,影响应用的流畅度
  2. 尽量减少内存泄漏,避免OOM
常见的内存泄漏原因:
  1. list map容器中有大量对象,容器使用完没有及时的清理

  2. 类的静态变量,持有大数据对象(bitmap)

  3. Handler临时性的内存泄漏(内部类持有外部类)

  4. 改变哈希值

  5. 非静态内部类的静态实例

  6. 资源对象未关闭(数据库操作、网络、IO输入输出流连接)

  7. 注册的对象为注销()

  8. 静态集合类:容器为静态,那么它们的生命周期与程序一致,容器中的对象不会在程序结束前释放,从而造成内存泄漏

  9. 各种连接:数据库、网络、IO连接等,不用或者使用完毕就要释放关闭

  10. 变量不合理的作用域:一个变量的定义范围大于其使用范围,很有可能造成内存泄漏(比如:局部变量赋值内容,紧接着可以保存数据库,然而保存后,该变量随着方法的结束而释放,如果把局部变量,改成成员变量,那么保存数据库后,该变量生命周期同对象,方法结束后变量不能回收,一次造成泄漏)

  11. 内部类持有外部类

  12. 改变哈希值:当一个对象被存储进HashSet集合中,就不能修改这个对象中那些参与计算哈希值的字段,否则修改后的对象的哈希值与最初存储进HashSet中的哈希值就不同了,这就导致删除当前对象失败,造成内存泄漏

注意事项避免内存消耗过多:
  1. AutoBoxing自动装箱过程
  2. 内容复用
    (1).有效利用系统自带的资源
    (2).视图复用(viewholder)
    (3).对象池
    (4).Bitmap对象复用
  3. 使用最优的数据类型
    (1).当对象的数目在1000以内且特别多访问而删除和插入不高的情况尽量用ArrayMap代替HashMap
    (2).枚举最大的有点就是安全、易读,但是内存消耗是定义常量的三倍以上,可以用注解的方式来检查安全
    (3).使用IntDef和StringDef来检查类型安全
    (4).LruCache建议使用这个缓存机制,但是既不能分配太大,也不能分配太小
  4. 图片内存优化
    (1).使用位图规格,使用inSampleSize实现位图的缩放和压缩。使用缓存机制等
Android虚拟机中有几种类型GC日志:
  1. GC_CONCURRENT:当应用进程中的Heap内存占用上涨时,避免因Heap满了而触发的GC
  2. GC_FOR_MALLOC:因GC_CONCURRENT没有执行完,而应用又需要更多的内存,这时就不得不停下来进行MALLOC GC
  3. GC_EXTERNAL_ALLOC:这时为external分配的内存执行达到GC
  4. GC_HPROF_DUMP_HEAP:创建HPROF profile的时候执行
  5. GC_EXPLICIT:显式的调用的system.gc()执行。一般来说,可以信任系统的GC机制,尽量不去显式调用System.gc()方法,减少不必要的系统开销,影响应用的流畅度
  6. 在ART模式下日志多了一个Large Object Space(大对象占用的空间),这部分内存并不是分配在堆上的,但仍属于应用程序内存空间,主要用来管理Bitmap等占内存大的对象,避免因分配大内存导致频繁GC
内存分析工具:

Memory Monitor:内存、CPU、网络的分析工具

上一篇 下一篇

猜你喜欢

热点阅读