美文网首页JavaAndroid
内存回收机制

内存回收机制

作者: 码农修行之路 | 来源:发表于2020-11-29 22:47 被阅读0次
clipboard.png

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

  • Young Generation:年轻一代(不断更替,当年轻一代eden区域满了的情况下,还存活的对象被复制到Survivor0区域空间中,当Survivor0区域满了,此区存活的对象会被复制到另一个Survivor1区域,当Suevivor1也满了的时候,从Survivor0中复制还存活的对象到Old Generation中,其余的回收,这时候Survivor1和Sorvivor0角色互换)

  • Old Generation:老年一代(当年青一代中Survivor0和Survivor1转换一定次数后,还存活的对象被复制到Old Generation中,此时生命周期比较长)

  • Permanet Generation:持久一代(当存活的对象在Old Generation区域停留时间达到一定程度后,会被移动到Old Generation,最后累积一定时间再移动到Permanent Generation区域,几乎免疫内存垃圾回收器,活的最长久的一代人)

  • 系统在Young Generation 和 Old Generation上采用不同的回收机制,每一个Generation都有一个固定的大小,随着新对象的不断被分配到此区域,当对象总的大小临近这一区域的内存阈值的时候,就会触发GC操作,以便腾出内存空间来存放新的对象

  • 执行GC占用的时间和它在哪个Generation区域有关,Young Generation执行时间最短,Old Generation其次,Permanent Generation执行时间最长,同时Gc的执行时间也和当前Generation中对象的数量有关,Generation中对象数量越多,执行时间越长
    垃圾回收机制算法:

  • 针对Young Generation 通常存活时间最短,因此基于Copying算法回收,所谓的Copying算法就是扫描出存活的对象,并复制到一块新的完全未使用的空间中,对应于Young Generation,就是在eden、FromSpace或TopSpace之间copy,新一代采用空间指针的方式控制Gc触发,指针保持最后一个分配的对象在Young Generation区间的位置,当有新的对象要分配内存时,检查内存空间是否足够,不够就触发Gc,当连分配对象时,对象会逐渐从eden到Survivor,最后到Old Generation

  • Old Generation相比较Young Generation存活时间较长,比较稳定,所以采用标记算法来回收。所谓的标记就是标记出存活的对象,然后回收未被标记的对象,回收后对空的内存空间要么进行合并、要么标记出来以便于下次进行分配,以减少内存碎片带来的效率损耗。

android系统中Gc有三种类型:
  • kGcCauseForAlloc:在分配内存时内存不足的情况下引起的Gc,这种情况下Gc会stop world ,stop world是由于并发Gc时,其它线程都会停止工作。
  • kGcCauseBackground:当内存达到一定的阈值的时候引发的Gc,这个时候一个后台Gc不会引起stop world。
  • kGcCauseExplicit:显示调用时进行的Gc,如果ART打开了这个选项,在system.gc()时会进行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
  • 在DVM虚拟机下,GC都是并发的,也就是说每次触发GC都会导致其它线程工作的暂停(包括UI线程)。而在ART模式下,在GC时,不像DVM仅有一种算法,ART在不同的情况下会选择不同的回收算法

  • 在GC方面,相比DVM,ART更为高效,不仅仅是GC的效率大大缩短了Pause的时间,而且在内存分配上对大内存分配单独的区域,有算法在后台做内存整理,减少内存碎皮,因此在ART模式下,避免较多的类似GC导致的卡顿问题。

内存分析工具:

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

相关文章

  • python拾遗7 - 垃圾回收

    垃圾回收机制 相比 C++ 的手动回收内存,python 的垃圾回收机制可谓是省心省力,判断是否回收一块内存,主要...

  • 对 Java 内存的一些理解-[Android_YangKe]

    Java 垃圾回收机制优点 Java 内存模型 什么是内存抖动 什么是内存泄漏 垃圾回收机制常见算法 Java 垃...

  • Redis 对象共享、内存回收、空转时长

    内存回收 C 语言不具备内存回收功能,所以 Redis 构建了一个由引用计数实现的内存回收机制,通过这一机制,程序...

  • 2018-10-13

    浅谈浏览器的垃圾回收机制和内存泄露 JavaScript使用垃圾回收机制来自动管理内存。 JS的回收机制分两种:1...

  • try catch finally

    java的垃圾回收机制不会回收任何的物理资源,垃圾回收机制只回收堆内存中对象所占用的内存 当程序执行try块,ca...

  • 2018-11-19 python学习第三天

    1、内存回收机制: 在其他语言中需要考虑内存回收机制,垃圾数据太多会导致内存溢出。但是python语言无需考虑这点...

  • JS垃圾回收机制(内存问题)

    垃圾收集机制理解 垃圾收集机制:释放无用的数据,回收内存。 垃圾收集机制分类:1)自动回收 2)手动回收 垃圾收集...

  • 直击面试,聊聊 GC 机制

    GC 中文直译垃圾回收,是一种回收内存空间避免内存泄漏的机制。当 JVM 内存紧张,通过执行 GC 有效回收内存,...

  • JavaScript的垃圾回收机制

    大纲 1、认识垃圾回收机制2、垃圾回收机制的原理3、垃圾回收机制的标记策略4、垃圾回收机制与内存管理 1、认识垃圾...

  • python内存管理机制

    Python内存管理机制 Python内存管理机制主要包括以下三个方面: 引用计数机制 垃圾回收机制 内存池机制 ...

网友评论

    本文标题:内存回收机制

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