MyDog--核心--GC

        gc就是内存管理的一类算法,基本上都是通用型的大路货,鲜有专门为特定情况设计特定算法。本质上就3种算法:标识法、引用计算、内存拷贝。具体可以参考:一文搞懂七种基本的GC垃圾回收算法-腾讯云开发者社区-腾讯云 (tencent.com)

        而mydog的gc算法却是针对mydog的内存布局设计的特定算法。首先我们要搞清楚,gc是为了啥?就是方便编码,程序员只需要new,不需要关心如何delete。其次,我们看看mydog内存布局:

  1. 其实有些数据是不需要gc的,比如表格,配置,事件等,因为它们是满格的生命周期或者是无需别人引用。
  2. 有些数据,特别是属性集,它们可以通过引用失效的方法而避开gc。比如角色B,C,D追着A砍,如果A下线了,那么A的属性集内存就要被回收(或释放),这时候B,C,D引用了A的某个属性集,那么当它们需要知道A的当前坐标时,发现引用失效。
  3. 剩下的,就是执行逻辑指令时候,可变数据大小结构的数据,就真的需要gc。

MyDog设计的gc算法,本质是延后释放+引用失效+内存池。只针对可变数据大小结构的数据进行gc。gc最核心的是垃圾回收的时机!

MyDog内存的释放(归还给池)时机分3种:(可变数据大小结构的引用,在C++中用指针实现)

  1. 生命周期结束,是指脚本语法中,大括号{}包括起来的临时数据,执行到}时候,那么里面所申请的数据会释放。这个和C++的临时变量一样的生命周期。和C++不一样的是,脚本里是可以打破释放时机的,比如return临时变量的引用。
  2. 函数体结束,有关键字new的数据,在所在的函数运行结束时进行释放(C++是整个应用周期,直到delete才释放)。同样有打破释放时机的机制。
  3. 数据离线,特指角色下线,那么就要释放对应的属性集。这里必须有个可以检测引用是否失效的机制。

打破释放时机打破时机后,数据跟随释放

  1. 数据带到属性集里,数据成为属性集的一部分,跟随属性集释放。
  2. 数据存入复容器里,复容器指vector,map,set这些。
  3. 返回到下一个函数体里。

引用失效机制

  1. 每次使用前都要获取引用数据,获取不了就要做对应处理
  2. 通过key对数据做记录标识,通过key查找数据
  3. key不能是内存地址,因为池的存在,你可能刚释放数据后,下一个指令就得到通用地址的数据,这时候的数据并不是你需要引用的数据。
  4. key由池地址(8bit)+记录累计次数(24bit)组成。
  5. 不要对高频创建的实体进行引用,比如战斗技能产生的火球,buff等。因为首次引用会产生记录,记录次数占24bit。客户端还凑合,服务器就很容易因为记录次数溢出导致错误引用。角色不属于高频,就算1s一个,也要179天后才重复。当然你也可以将key扩展成52bit,只是比较占内存而已

具体的实现是比较复杂的。

  1. 固定大小的数据都是在寄存器里创建,比如int,double等。而那些可变数据大小结构,比如string,vector<XXX>等,会内置一些具体的,常用的结构.具体看EPtrType。当然支持脚本定义的结构!
  2. 上述的内置结构都是要延后delete的,所以使用MDMemPtr统一封装起来,在寄存器有个set容器存储这些MDMemPtr。有点小纠结的是到底使用set还是unordered_set。其实小数据内,效率是差不多的,而set才占24字节,unordered_set就占80字节!最后还是选了set
  3. 在编译脚本的阶段,有些时候是可以确定内置结构不需要延后delete的,所以并不是一创建内置结构的时候就要存储对应的MDMemPtr
  4. 剩下的就是打破释放时机引用失效机制

MyDog--前言和目录(附源码链接)-CSDN博客

  • 14
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值