对于内存的管理,是程序在应用的时候的必需知识点,《Lua设计与实现》中对Lua语言的GC原理做了一个详细的讲解,云风的blog也对其进行了详尽的讲解Lua GC 的源码剖析 系列
给出作者 codedump 在github上的lua源码链接:https://github.com/lichuang/Lua-5.1.4-codedump
这儿就继续做《Lua设计与实现》的阅读笔记,对Lua GC原理及其过程做一个详尽的讲解,由于篇幅较大,就一分为二,写上下篇来讲解整个过程。
 
一、GC的原理及其算法设计
不同的语言,对GC算法的设计不同,常见的GC算法是引用计数和Mark-Sweep算法, c#采用的是Mark-sweep && compact算法, Lua采用的是Mark-sweep算法,分开说一下:
引用计数算法:在一个对象被引用的情况下,将其引用计数加1,反之则减1,如果计数值为0,则在GC的时候回收,这个算法有个问题就是循环引用。
Mark-sweep算法:每次GC的时候,对所有对象进行一次扫描,如果该对象不存在引用,则被回收,反之则保存。
在Lua5.0及其更早的版本中,Lua的GC是一次性不可被打断的过程,使用的Mark算法是双色标记算法(Two color mark),这样系统中对象的非黑即白,要么被引用,要么不被引用,这会带来一个问题:在GC的过程中如果新加入对象,这时候新加入的对象无论怎么设置都会带来问题,如果设置为白色,则如果处于回收阶段,则该对象会在没有遍历其关联对象的情况下被回收;如果标记为黑色,那么没有被扫描就被标记为不可回收,是不正确的。
 
为了降低一次性回收带来的性能问题以及双色算法的问题,在Lua5.1后,Lua都采用分布回收以及三色增量标记清除算法(Tri-color incremental mark and sweep)
 
其基本的原理伪代码,参考书中原文为:
每个新创建的对象颜色设置为白色
//初始化阶段
遍历root节点中引用的对象,从白色置为灰色,并且放入到灰色节点列表中
//标记阶段
while(灰色链表中还有未扫描的元素):
从中取出一个对象,将其置为黑色
遍历这个对象关联的其他所有对象:
if 为白色
标记为灰色,加入到灰色链表中(insert to the head) //回收阶段
遍历所有对象:
if 为白色,
没有被引用的对象,执行回收
else
重新塞入到对象链表中,等待下一轮GC
二、GC的数据结构
分析Lua中对于需要GC的类型数据
#define iscollectable(o) (ttype(o) >= LUA_TSTRING)
都会有一个基本的定义CommonHeader,其定义为:
 
next: GCObject链表指针,该指针用来将所有的GC对象都链接在一个表中;
tt: 数据类型:nil, boolean, number, string...
marked: 标记字段,byte表示的字段颜色定义为
这儿特定解释一下为什么会有两种白色,前面提到,5.1后的Lua采用的是三色标记算法,其实质是四色标记算法,分为0型白色和1型白色,在GC回收的时候,会设置当前的白色为其中一种,详见globalstate中的currentwhite,这样在代码回收的时候,如果当前对象的白色不为currentwhite,则认为其不可回收,这样的对象需要等到下一次的GC才能决定是否回收,具体参看后面的,会有对应的应用。对于global_state的设计为:
具体的参数的作用,详见注释,就不在一一解释了
 
三、GC的流程
1、数据的创建
想要了解GC的过程,首先看看数据是怎么在创建的时候被链接到GC链表中的,主要分为三种数据的创建
1) 一般数据的创建 luaC_link
 
简单直接,直接insert to the head
2) upval的创建 luaC_linkupval
3) userdata(udata)的创建 luaS_newdata
 
2、开始GC
整个GC过程分为五个阶段,其定义为
其执行GC的函数为singlestep,来看第一步的操作:
进一步看看markroot的操作:
 
其实就是reset一遍相关的变量,然后标记mainthread, G表,registry表,然后切换到下一个标记阶段。
参看定义:
 
最后都要执行reallymarkobject函数(此处需要展示一下我的竖屏截图便利了:D):
 
基本的注释都解释了各个对象是如何的处理的,udata是不会引用其他类型的数据,所以一步到黑色,upvalue则根据是否为close来决定是否标记到黑色,open状态的upvalue变化较为频繁,需要在后面的remarkupvals中解决。
写到这儿,已经写很长了,为了阅读的便利,让我们下一篇文章继续GC的进程吧:D

深入探究Lua的GC算法(上)-《Lua设计与实现》的更多相关文章

  1. 深入探究Lua的GC算法(下)-《Lua设计与实现》

    紧接着上一篇文章zblade:深入探究Lua的GC算法(上)-<Lua设计与实现> 这篇文章让我们收尾GC的具体后续操作.转载请标明出处:http://www.cnblogs.com/zb ...

  2. 浅谈c#和lua的gc

    前提: 本文参考和借鉴相关博客,相关版权归其所有,我只是做一个归纳整理,所以本文没有任何版权 参考文献和书籍: CLR和.Net对象生存周期:   https://www.cnblogs.com/Wd ...

  3. lua在MacOS系统上的安装方法

    lua是一种非常小巧的脚本语言,由标准C编写而成,可以很方便的调用c/c++或者被c/c++.另外相关的还有一个luaJIT,是lua在某些平台上的编译器. 我们在这里只安装lua. 1.检测电脑上是 ...

  4. 深入探究jvm之GC的算法及种类

    一.GC基本概念 GC(Garbage Collection)垃圾收集,1960年最早在List中使用.在Java中GC回收的对象是堆空间和永久区,可以有效避免程序员人为造成内存泄漏问题.将堆空间和永 ...

  5. Redis | 第9章 Lua 脚本与排序《Redis设计与实现》

    目录 前言 1. Lua 脚本 1.1 Redis 创建并修改 Lua 环境的步骤 1.2 Lua 环境协作组件 1.3 EVAL 命令的实现 1.4 EVALSHA 命令的实现 1.5 脚本管理命令 ...

  6. 46张PPT讲述JVM体系结构、GC算法和调优

    本PPT从JVM体系结构概述.GC算法.Hotspot内存管理.Hotspot垃圾回收器.调优和监控工具六大方面进行讲述.(内嵌iframe,建议使用电脑浏览) 好东西当然要分享,PPT已上传可供下载 ...

  7. JVM学习(4)——全面总结Java的GC算法和回收机制

    俗话说,自己写的代码,6个月后也是别人的代码……复习!复习!复习!涉及到的知识点总结如下: 一些JVM的跟踪参数的设置 Java堆的分配参数 -Xmx 和 –Xms 应该保持一个什么关系,可以让系统的 ...

  8. jvm系列(三):java GC算法 垃圾收集器

    GC算法 垃圾收集器 概述 垃圾收集 Garbage Collection 通常被称为“GC”,它诞生于1960年 MIT 的 Lisp 语言,经过半个多世纪,目前已经十分成熟了. jvm 中,程序计 ...

  9. JVM GC算法 CMS 详解(转)

    前言 CMS,全称Concurrent Low Pause Collector,是jdk1.4后期版本开始引入的新gc算法,在jdk5和jdk6中得到了进一步改进,它的主要适合场景是对响应时间的重要性 ...

随机推荐

  1. hashMap 方法详解

    http://www.iteye.com/topic/754887 /** * 扩展散列表的容量 * @param newCapacity */ void resize(int newCapacity ...

  2. 创建线程的第三种方式——使用Callable接口

    Callable是类似于Runnable的接口,实现Callable的类和实现Runnable的类都是可被其他线程执行的任务. 优点:有返回值 缺点:实现繁琐 简单实现: CallableAndFut ...

  3. CF719E. Sasha and Array [线段树维护矩阵]

    CF719E. Sasha and Array 题意: 对长度为 n 的数列进行 m 次操作, 操作为: a[l..r] 每一项都加一个常数 C, 其中 0 ≤ C ≤ 10^9 求 F[a[l]]+ ...

  4. 吻逗死(windows)系统下自动部署脚本(for java spring*)及linux命令行工具

    转载请注明出处:https://www.cnblogs.com/funnyzpc/p/10051647.html (^^)(^^)自動部署腳本原本在上個公司就在使用,由於近期同事需要手動部署一個Spr ...

  5. angular1.3 video

    video标签动态获取播放链接是出现 Error: $interpolate:interr Interpolation Error Error: $sce:insecurl Processing of ...

  6. bindservice与Activity通信

    package com.example.jikangwang.myapplication; import android.content.ComponentName; import android.c ...

  7. ABAQUS/CAE——Context

    Part(部分) 用户在Part单元内生成单个部件,可以直接在ABAQUS/CAE环境下用图形工具生成部件的几何形状,也可以从其他的图形软件输入部件.详细可参考ABAQUS/CAE用户手册第15章. ...

  8. 【转】Android studio安装与配置

    Android studio安装与配置 1.首先下载Android studio安装包,可以从http://www.android-studio.org/下载最新版本,这里采用3.0版本进行演示,对应 ...

  9. SparkStreaming+Kafka整合

    SparkStreaming+Kafka整合 1.需求 使用SparkStreaming,并且结合Kafka,获取实时道路交通拥堵情况信息. 2.目的 对监控点平均车速进行监控,可以实时获取交通拥堵情 ...

  10. 怎样做ie兼容性

    1.<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />强制把不标准的转 ...