zoukankan      html  css  js  c++  java
  • Lua5.1 三色标记gc

    白色:待回收的对象
    灰色:待遍历的对象
    黑色:不回收的对象

    主要流程:
    1、从根集开始遍历
    2、遍历到的白对象标灰入栈,遍历到灰色、黑色对象则跳过。
    3、每次从栈中pop一个灰色对象标黑,并遍历它引用的对象(处理方式参考2)
    4、直到栈为空,一次性将白色对象清理出内存。

    流程特点:
    第2、3步是可以分步进行的,但是要对新元素进行处理,避免遍历遗漏。

    如何遍历table:
    1、table要么没有被遍历到,整个被回收,要么其所有key、value最终是黑色,不会被回收
    2、如果table的key、value都被设置了weak,那不用遍历了,这些key-value肯定要被回收,将table直接挂g->weak即可(table本身不回收)
    如果table的key被设置了weak,这些key不需要遍历,肯定是要被回收,放白
    如果table的value被设置了weak,这些value不需要遍历,和key同理
    只要key被回收,整个key-value肯定是要从table中移除的,虽然不一定回收value。(value同理)
    3、设置了weak的table需要标灰,但不再入栈。

       为什么不标黑,因为这样可以防止被再次被置灰入栈吗?参考<往table插入新数据>
       那么标黑会怎样?
       1) 如果是往其他table插入这个table,这个table本来就是黑色的,原逻辑啥也不干。没问题!
       2) 如果是往这个table添加元素,根据下面<往table插入新数据>,可能会被置灰入栈,
    	  但这其实是没必要的,因为这个table已是weak,不用遍历其元素了。
    	
    4、元表metatable也会被遍历到
    

    往table插入新数据:
    1、若table是白色的,不用管它,有被引用最后肯定会被遍历到,没有的话回收也是应该
    2、若table是灰色的,不用管它,反正一会就遍历到它,它的新数据也会遍历到
    3、若table是黑色且新数据是白色,将table置灰入栈待重新遍历。(将新数据置灰入栈也行,省去重新遍历已经遍历过的元素)

    闭包(函数)如何遍历:
    函数里其实是有很多对象是引用到的,比如upvalue。
    需要将这些引用到的所有upvalue都遍历一下。

    字符串如何回收:

    线程如何回收:
    线程引用的对象都在栈里,遍历栈即可

    其他类型如何回收:

    两种白色是啥:

    https://blog.codingnow.com/2011/03/lua_gc_1.html

  • 相关阅读:
    在intelij IDEA中添加对jetBrick文件的识别
    Android ScrollView 和ListView 一起使用的问题汇总
    关于android 内存的笔记
    Android 内存
    Adb 获取手机信息
    ADB command
    org.apache.http 源代码下载
    用Fiddler查看 Android/iOS 网络请求
    java Enum 类型互转
    InstallShield 制作MSI
  • 原文地址:https://www.cnblogs.com/xcw0754/p/12451635.html
Copyright © 2011-2022 走看看