• 垃圾回收算法学习


    垃圾 -> 程序不用的内存空间

    gc要做什么 -> 找到垃圾,回收垃圾

    为什么要回收 -> 因为只分配不释放会内存泄漏,占满内存,系统崩溃

    释放需要注意什么 -> 正确释放 -> 防止悬垂指针(指向释放完毕的空间)/防止释放正在使用的空间

    GC操作的基本单位是对象,对象包含对象头(对象的大小种类,根据不同gc算法所需的信息)和域(对象使用者可以引用或替换)

    gc分配堆内存空间 -> mutator要求在堆中存放对象 -> 堆满进行gc -> 如果还不够则尝试增大堆

    根 (全局变量,寄存器,调用栈)

    gc评价标准: 吞吐量(单位时间的处理能力,比如复制算法只检查活动对象,标记清除算法检查所有活动和非活动对象,随着对象类型占比不通则效率不通),最大暂停时间(因为执行gc而导致的暂停执行的最长时间),堆使用率(复制能用一般,标记清除都能用),访问局部性(为了更好的利用存储器,寄存器->缓存->内存->辅助存储,将更有用的数据加载到更小但更快的存储中使用,用临机预读,引用关系对象预加载等方式提升)

    标记清除

    标记所有活动对象(所以标记花费的时间与活动对象的总数成正比,采用深度优先遍历),清除那些没有标记的非活动对象(遍历所有堆,所以堆越大,清除花费的时间越长,将非活动对象作为分块,连接到空闲列表,之后遍历空闲链表就可以找到可用分块了),分配(将回收的垃圾进行再利用,搜索空闲链表并寻找合适大小的分块-或者找到最合适的,或者找到第一个能装下的,最差不可用的是找最大的)

    合并:在清除阶段将连续的小分块连接在一起形成一个大的分块

    缺点:碎片化,分块不连续,遍历空闲链表时间不确定,可能在最头也可能在最后,因为每次都要给对象头写标识所以根写时复制不兼容

    措施:多个大小不同的空闲链表,用空闲链表数据管理,或将大小相近的对象整理成固定大小的块进行管理,位图标记法,延迟清除只在分配时执行必要的遍历

    引用计数器

    在对象头中记录有多少程序应用了这个对象,在mutator的处理过程中通过增减计数器的值来进行内存管理,更新引用的时候,先对新引用对象的计数器+1,再对之前引用的对象-1,再更新引用关系,先+1再-1是为了防止同一个对象的时候-1被回收了就没办法+1了。

    优点:

    立即回收:引用计数算法中会监督在更新指针的时候是否产生垃圾,从而在产生垃圾的时候立即回收,而标记清除即使产生了算法也不立即回收,而是只会在没有分块的时候将垃圾一并回收

    最大暂停时间短:只有当通过mutator更新指针时程序才会回收垃圾

    没有必要沿指针查找

    缺点:计数器值的增减处理繁重,计数器需要占用很多位 空间利用率下降,实现繁琐,循环引用无法回收

    升级:

    延迟引用计数器:从根引用的指针的变化不反映在计数器上,使用zct表,事先记录下计数器值在def_ref_cnt函数作用下变为0的对象。如果没空间了再scan_zct把所有通过根直接引用的对象的计数器都进行增量,反应到计数器值上

    优点是延迟了根引用计数器的技术,将垃圾一并回收,减轻了根引用频繁变化而导致的计数器增减锁带来的额外负担

    缺点是引用计数器的增减有延迟,垃圾无法马上回收

    strcky:

    减少计数器位宽,

    1位引用计数法

    部分标记清除算法

  • 相关阅读:
    android studio 手把手叫你NDK开发环境搭建及基础使用
    android——Tinker启蒙,献给热修复一脸懵逼的自己
    android——webview拦截跳转指定url后,点击返回界面重定向的问题
    android——使用Ijkplayer打造自己的超级电视台播放软件
    android——webview解决goback()后,界面会刷新的问题
    android——webview动态修改html界面
    android——webview修改html界面,达到去除或隐藏部分界面的效果
    项目总结——开篇
    android——使用观察者模式打造跨线程、跨界面等一对多通讯
    使用material design 打造炫酷的“宜城头条”app
  • 原文地址:https://www.cnblogs.com/it-worker365/p/8943731.html
Copyright © 2020-2023  润新知