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

  • 相关阅读:
    JavaScript自定义事件
    用Java构建一个简单的WebSocket聊天室
    PHP实现支付宝小程序用户授权的工具类
    jq ajax超时设置
    gulp使用笔记
    vue学习—组件的定义注册
    echarts设置线条粗细
    求js数组的最大值和最小值
    js删除数组中的 "NaN"
    jq方法(end)
  • 原文地址:https://www.cnblogs.com/xcw0754/p/12451635.html
Copyright © 2011-2022 走看看