1.golangç¼ç¨è¯è¨ï¼
2.tolua源码分析(五)lua使用C#的enum
3.虚幻学习资料整理
4.Lua GC机制分析与理解-上
5.LuaJIT源码分析(二)数据类型
6.图解Lua分代GC
golangç¼ç¨è¯è¨ï¼
为ä»ä¹è¦å¦ä¹ Golangï¼
Goè¯è¨å ¶å®æ¯Golanguageçç®ç§°ï¼Goï¼å称Golangï¼æ¯GoogleçRobertGriesemerï¼RobPikeåKenThompsonå¼åçä¸ç§éæ强类åãç¼è¯å¹¶ååè¯è¨ãGoè¯è¨è¯æ³ä¸Cç¸è¿ï¼ä½åè½ä¸æï¼å åå®å ¨ï¼GCï¼åå¾åæ¶ï¼ï¼ç»æå½¢æåCSP-style并å计ç®ã该è¯è¨çå祥ç©ä¸ºéè±é¼ ï¼gordonï¼ï¼
éè±é¼ ï¼gordonï¼
Goè¯è¨ç¹è²ââç®æ´ãå¿«éãå®å ¨ã并è¡ãæ趣ãå¼æºãå å管çãæ°ç»å®å ¨ãç¼è¯è¿ é
Goè¯è¨ç¨éï¼Goè¯è¨è¢«è®¾è®¡æä¸é¨åºç¨äºæè½½Webæå¡å¨ï¼åå¨é群æ类似ç¨éçå·¨åä¸å¤®æå¡å¨çç³»ç»ç¼ç¨è¯è¨ã对äºé«æ§è½åå¸å¼ç³»ç»é¢åèè¨ï¼Goè¯è¨æ çæ¯å¤§å¤æ°å ¶å®è¯è¨æçæ´é«çå¼åæçãå®æä¾äºæµ·é并è¡çæ¯æï¼è¿å¯¹äºæ¸¸ææå¡ç«¯çå¼åèè¨æ¯å好ä¸è¿äºã
C/C++çé®é¢ï¼å¼åæçä½ï¼å¯¹å¼åè è¦æ±é«ï¼libcåªååå ¼å®¹ï¼è¿ç»´é¾åº¦å大ã
Lua/Pythonçé®é¢ï¼å¨æè¯è¨ï¼ç¼ºå°ç¼è¯è¿ç¨ï¼ä½çº§é误é¢åºï¼ç¼ºå°ææçæ§è½åæåè°è¯å·¥å ·ã
é¾ä¹æè²å¨çº¿æä¸å¦ç¡åæ°åºåé¾ææ¯å·¥ä½ç«æ¯ä¸å½æè²é¨å¦æ ¡è§å建设åå±ä¸å¿å¼å±çâæºæ §å¦ä¹ å·¥åº-å¦ç¡åæ°å·¥ä½ç«âå¯ä¸è·åçâåºåé¾ææ¯ä¸ä¸âè¯ç¹å·¥ä½ç«ãä¸ä¸ç«ç«è¶³ä¸ºå¦çæä¾å¤æ ·åæé¿è·¯å¾ï¼æ¨è¿ä¸ä¸å¦ä½ç 究ç产å¦ç ç»åå¹å »æ¨¡å¼æ¹é©ï¼æ建åºç¨åãå¤åå人æå¹å »ä½ç³»ã
golangæ¯ä»ä¹ææ
Goè¯è¨(å称Golang)æ¯GoogleçRobertGriesemerï¼RobPikeåKenThompsonå¼åçä¸ç§éæ强类åãç¼è¯åè¯è¨ãGoè¯è¨è¯æ³ä¸Cç¸è¿ï¼ä½åè½ä¸æï¼å åå®å ¨ï¼GC(åå¾åæ¶)ï¼ç»æå½¢æåCSP-style并å计ç®ãæ©å±èµæ
Goè¯è¨ä¸»è¦ç¨ä½æå¡å¨ç«¯å¼åï¼å ¶å®ä½æ¯ç¨æ¥å¼åâ大å软件âçï¼éåäºå¾å¤ç¨åºåä¸èµ·å¼å大å软件ï¼å¹¶ä¸å¼åå¨æé¿ï¼æ¯æäºè®¡ç®çç½ç»æå¡ãGoè¯è¨è½å¤è®©ç¨åºåå¿«éå¼åï¼å¹¶ä¸å¨è½¯ä»¶ä¸æç'å¢é¿è¿ç¨ä¸ï¼å®è½è®©ç¨åºåæ´å®¹æå°è¿è¡ç»´æ¤åä¿®æ¹ãå®èåäºä¼ ç»ç¼è¯åè¯è¨çé«ææ§åèæ¬è¯è¨çæç¨æ§åå¯äºè¡¨è¾¾æ§ã
Goè¯è¨ä½ä¸ºæå¡å¨ç¼ç¨è¯è¨ï¼å¾éåå¤çæ¥å¿ãæ°æ®æå ãèææºå¤çãæ件系ç»ãåå¸å¼ç³»ç»ãæ°æ®åºä»£çç;ç½ç»ç¼ç¨æ¹é¢ï¼Goè¯è¨å¹¿æ³åºç¨äºWebåºç¨ãAPIåºç¨ãä¸è½½åºç¨ç;é¤æ¤ä¹å¤ï¼Goè¯è¨è¿å¯ç¨äºå åæ°æ®åºåäºå¹³å°é¢åï¼ç®åå½å¤å¾å¤äºå¹³å°é½æ¯éç¨Goå¼åã
goè¯è¨çå ¨ç§°Goå ¨ç§°Golangã
Goè¯è¨ç±Googleå ¬å¸å¼åï¼å¹¶äºå¹´å¼æºï¼ç¸æ¯Java/Python/Cçè¯è¨ï¼Goå°¤å ¶æ é¿å¹¶åç¼ç¨ï¼æ§è½å ªæ¯Cè¯è¨ï¼å¼åæçè©æ¯Pythonï¼è¢«èªä¸ºâä¸çºªçCè¯è¨âã
Goè¯è¨å¨äºè®¡ç®ã大æ°æ®ãå¾®æå¡ãé«å¹¶åé¢ååºç¨åºç¨é常广æ³ãBAT大åæ£å¨æGoä½ä¸ºæ°é¡¹ç®å¼åçé¦éè¯è¨ã
å·ä¸ªgoæ¯ä»ä¹å·ä¸ªgoæ¯ä»ä¹
å¼éè麻goçä½ç¨å°±æ¯å¨ä¼åå¨æå ï¼å®é 享åçä¼æ éé¢ãè麻goå ¶å®å°±æ¯ç»æ们å 享ååºå®¶çä¼æ ï¼äº«åçé¢åº¦è¾¾å°æè è¶ è¿äºä¼åè´¹ç¨ï¼æ们åæ¯ä»ä¼åè´¹ç¨ï¼å¦æ享åå°çä¼æ è¾¾ä¸å°æ ï¼å°±ä¸ç¨æ¯ä»è´¹ç¨ã
2.æ们æå¼æ¯ä»å®ç¹å»âæçâæé®ã
3.ç¶åå¨çé¢ç¹å»æå¼è麻信ç¨ã
4.ç¶åå¯ä»¥çå°ä¸é¢ççé¢éé¢æä¸ä¸ªè½»ä¼åï¼ç¹å»è¿å ¥ï¼åç»å¯è½é½ä¼æ¾ç¤ºçæ¯è麻goäºã
5.è¿å ¥å°çé¢ï¼å°±å¯ä»¥çå°ç¸å ³çä¸äºå家çä¼æ å¸äºï¼æ们ç¹å»èªå·±éè¦çè¿å ¥ã
6.å°±å¯ä»¥çå°ä¸é¢æ¾ç¤ºçæä¸ä¸ªä¼æ å¸è¯¦æ ï¼æ们æå¼å¯ä»¥çä¸ä¸è¿ä¸ªæ¯ä¸æ¯æ们éè¦çã
7.ç¶åä¸é¢é½ä¼æè¿ä¸ªä¼æ å¸ä½¿ç¨çè¦æ±ï¼è¾¾å°äºæ个é¢åº¦ï¼å°±æ¯ä»ä¼åè´¹ç¨ï¼æ²¡æè¾¾å°ï¼éå享åçä¼æ å°±å¯ä»¥äºã
8.å¦æ确认è¿ä¸ªèªå·±æ¯æéè¦çï¼æ们就ç¹å»ä¸é¢çåæåè®®ï¼ç¶ååç»å°åºå°±å¯ä»¥ä½¿ç¨ä¼æ äºã
ä½ ä¸ºä»ä¹æ¾å¼golang?å 为å å管çç²ç³ãç»å¸¸çå°fmt.xxx导è´å åå ç¨å¤ªå¤ï¼åå°å¯¼è´å åå ç¨å¤ªå¤çæ±æ¨ã
goè¯è¨éååæå¡å¨ç»ä»¶ï¼é£ç§åä¸å¡æ°æ®æ å ³çæå¡å¨ãæ¯å¦æ°æ®åºæå¡å¨ãwebæå¡å¨ãæ¥å¿æç´¢å¼æçãå¦æç¨æ¥åä¸ä¸ªcrm管çç³»ç»ï¼é常累ï¼å 为缺ä¹å¥½å¤é«çº§ç¹æ§ååºå¤§ç第ä¸æ¹åºï¼èä¸è¯æ³æ¯è¾åä¸ï¼æ»ä½æè§å°±è·åå½ä»¤è¡å·®ä¸å¤ã
Goè¯è¨æ¯è°·æåå¸çç¼ç¨è¯è¨ï¼è¿ä¸ªè¯è¨åæçç®çï¼å°±æ¯ä¸ºäºå¨è¿è¡é度æ¥è¿C/C++è¯è¨çåºç¡ä¸ï¼æ³¨ææ¯æ¥è¿ï¼ï¼éä½å¼åè çé¨æ§ï¼åå°å¼åé¾åº¦ã
Goè¯è¨ï¼å¨åè½ä¸æ²¡æè¶ è¿C/C++ï¼éç¨è 为没æC/C++ç»éªçå¼åè ï¼å¼ååºæ¥è¿Cæççç¨åºã对äºå·²ç»çç»ææ¡C/C++çå¼åè æ¥è¯´ï¼Goè¯è¨æ²¡æä¼å¿ï¼è¿è¦éå¦è¯æ³ï¼éåºå¼åç¯å¢ï¼ææ¾æ¯ä¸ç¬¦åæççã
æ»ç»
å ¶å®è¯è¨è¿ä¸è¥¿ï¼é½æå ¶ä¼å¿åå£å¿ãèä¸æäºä¸è¥¿å¹¶ä¸æ¯çº¯ææ¯çãæ¯å¦javaçä¼å¿å¨äºæ¸ æ°çè¯æ表达ãå代ç çä¸éä¸é«ï¼ä½æ¯ä¸éä¹ä¸ä½ï¼éåå·¥ä¸å¼åã
ègoå¢ï¼ä¸å¾ä¸è¯´goå¨å¾®æå¡è¿åæå 天ä¼å¿ãæ¯ç«javaä¸è¦å®ç°goçå¾å¤åè½ï¼éè¦å¼å ¥ç¬¬ä¸æ¹åºãå¾ç¬¨éãègoåçæ¯æï¼è¿ä¸ªå¾®æå¡å°±å¾è½»å·§ãä½æ¯goçè¯æ³å¤ªæ´»ï¼å·¥ä¸ç¨æ¯ä¸ä¸ªæºå¤§çå¼ç«¯ã
Golangçç好ç¨åï¼å¥½ç¨ï¼ä¼ç¹å¦ä¸ï¼
并åç®åãæçé«
å½æ°å¯ä»¥è¿åå¤ä¸ªåæ°
åå¾åæ¶ï¼ç¸æ¯c/c++ãä¸è¿javaãc#é½æè¿ä¸ªä¼å¿ï¼
ç®åæä¸æï¼è¯è¨ç¹æ§å°ï¼ä¹ç®ç¼ºç¹ï¼
é å¥å·¥å ·å®åï¼pprof太好ç¨äºï¼
ç®ä»
Goï¼å称Golangï¼æ¯Googleå¼åçä¸ç§éæ强类åãç¼è¯åã并ååï¼å¹¶å ·æåå¾åæ¶åè½çç¼ç¨è¯è¨ã
ç½ä¼¯ç¹Â·æ ¼çå²è«ï¼RobertGriesemerï¼ï¼ç½å·派å ï¼RobPikeï¼åè¯Â·æ±¤æ®éï¼KenThompsonï¼äºå¹´9æå¼å§è®¾è®¡Goï¼ç¨åIanLanceTaylorãRussCoxå å ¥é¡¹ç®ãGoæ¯åºäºInfernoæä½ç³»ç»æå¼åçãGoäºå¹´ææ£å¼å®£å¸æ¨åºï¼æ为å¼æ¾æºä»£ç 项ç®ã
并å¨LinuxåMacOSXå¹³å°ä¸è¿è¡äºå®ç°ï¼åæ¥è¿½å äºWindowsç³»ç»ä¸çå®ç°ãå¨å¹´ï¼Go被软件è¯ä»·å ¬å¸TIOBEé为âTIOBEå¹´æä½³è¯è¨âãç®åï¼Goæ¯åå¹´åå¸ä¸ä¸ªäºçº§çæ¬ï¼å³ä»a.xå级å°a.yï¼ã
tolua源码分析(五)lua使用C#的enum
探讨了C#枚举如何在Lua中注册以及与普通类的注册区别。以官方提供的例子为例,展示了如何将C#的UnityEngine.Space类型的枚举推送到Lua层,并在Lua层面测试了诸如tostring、ToInt、Equals等接口,汉王纷争2021源码验证了在Lua层可以进行枚举的相等判断,以及将int转换为枚举或将枚举转换为int的操作。
在Lua层面表示C#的枚举,例子中在第行和第行将枚举推送到Lua层。由于枚举是值类型,C#层使用了enumMap缓存装箱后的object与枚举的映射关系。注册到Lua层的枚举类使用了EnumMetatable。
具体来看C#枚举注册到Lua的方法,例如在System_EnumWrap.Register方法中。在Lua层表示C#枚举的方式与普通类相似,但需要注意一些区别。
例如,当使用__tostring方法时,ToLua.ToObject将Lua栈上的userdata转换为object,通过userdata的index查找C#的object缓存,不会产生垃圾收集(GC)。同样地,ToInt方法中的CheckObject同样在C#的object缓存中查找,执行类型检查,也不会产生GC。
当比较C#的gee引擎源码泄露枚举与int类型时,由于使用了==操作符,这会触发装箱,产生一次GC。因此,在实际使用中应尽量避免在Lua层对C#枚举与number进行比较。而在Lua层直接比较两个C#枚举时,它们在Lua层被视为同一份userdata,因为它们来自于同一个C#缓存,index相同。
在将Lua栈上的number转换为C#枚举的实例时,IntToEnum方法在C#的UnityEngine_SpaceWrap类中实现。这个方法直接将double转换为int,再转换为UnityEngine.Space类型,避免了GC。在C#层推送到Lua层的枚举时,是从C#的缓存中取到枚举对应的object,然后推送到Lua层,也不会产生GC。
总结,在Lua使用C#的枚举时,从C#到Lua层的传递不会产生GC,在Lua层进行number与枚举类型之间的转换以及直接比较枚举时不触发GC。然而,当比较枚举与number时,会触发一次GC。针对这一情况,java源码推广系统可以进行针对性优化。
下一节将深入研究在开发中常见的C#委托/事件如何注册到Lua函数的实现。
虚幻学习资料整理
在虚幻学习资料整理中,官方文档、论坛、视频教程是核心途径。知乎与博客推荐的UE源码书籍提供深入理解与实战指南。
主题概述覆盖全面,GamePlay、相机、GameFeatures、EnhancedInput等核心模块讲解清晰。生命周期、启动流程、主循环的剖析,助你掌握虚幻引擎的基础与进阶。
C++蓝图、UMG、CommonUI动画系统,GAMES动画系列等教学资源,结合Advanced Locomotion System、RootMotion等高级技术,提升动画设计能力。
MetaHuman、AINavigation、行为树(HTN)与状态树,bjui系统源码下载深入探讨智能体与路径导航实现。同时,MassGAS与网络同步技术,是多人游戏开发的关键。
Lua与UnLua,材质、音效与Wwise,资源管理与热更新、Pak文件,物理载具与World Partition,PCG与粒子编辑器,3D数学与UObject,反射与GC,序列化与内存分配,多线程与Task Graph,这些都是构建高效、流畅虚幻游戏的基石。
Tim Sweeney演讲与图形渲染、图形学经典教程书籍,以及Unreal技术分享,提供了从理论到实践的全方位学习资源。这些资源是虚幻学习者不可或缺的宝库,能有效加速学习进程并提升技能水平。
Lua GC机制分析与理解-上
lua的垃圾回收(Garbage Collect)在lua编程中占据关键地位,尤其在5.3.4版本的源码中,本文将基于此版本进行深入探讨。dnf源码如何获得lua采用的是标记清除式GC算法,其流程包括标记和清除两步骤:标记阶段从若干根节点开始,逐层追踪相关对象;清除阶段遍历标记过的对象链表,删除不再需要的内存。
在lua的垃圾回收中,使用白、灰、黑三种颜色标识对象的状态。白色代表可回收状态,初始对象为白色,表示未被访问;灰色代表待标记状态,已访问但引用的其他对象未标记;黑色则表示对象已完全标记,不可回收。为了区分新建对象的特殊情况,lua引入了白1和白2,确保在标记阶段结束后的清除阶段,新创建的对象不会被错误地清除。
GC过程从新建对象开始,通过luaC_newobj函数创建可回收对象,并将其标记为白色。触发GC的条件包括手动调用或内存使用超过设定阈值。在lua5.1之后,引入了分步执行机制,提高了系统的实时性,核心函数singlestep负责管理整个过程。
标记阶段从根对象开始,将白色变为灰色,并加入灰色链表。清除阶段则根据对象类型分步进行,如字符串直接回收,其他类型逐个检查颜色并释放空间。整个过程非搬迁式,不涉及内存整理。
总结起来,lua的GC机制就是通过灰色链表进行标记,然后遍历内存链表进行清除。虽然本文主要基于5.3.4版本,但原理适用于不同版本的lua。任何理解或改进的建议,都欢迎读者批评指正,期待您的反馈,感谢阅读。
LuaJIT源码分析(二)数据类型
LuaJIT,作为Lua的高性能版本,其源码分析中关于数据类型处理的细节颇值得研究。它在数据结构的定义上与Lua 5.1稍有不同,通过通用的数据结构TValue来表示各种Lua数据类型,但其复杂性体现在了内含的若干宏上,增加了理解的难度。这些宏如LJ_ALIGN、LJ_GC、LJ_ENDIAN_LOHI、LJ_FR2等,分别用于内存对齐、GC模式的选择、大小端判断以及浮点数编码格式的选择。
LJ_ALIGN宏用于确保struct内存对齐,以提高内存访问效率。LJ_GC宏在当前平台为位且无强制禁用的情况下生效,表明LuaJIT支持位GC(垃圾回收)模式。LJ_ENDIAN_LOHI宏则根据平台的字节顺序来确定结构的布局,而x平台采用小端序。
对于TValue结构的定义,通过处理宏后可以简化为一个位的结构体,包含一个union,用于统一表示Lua的各种数据类型。这种设计利用了NaN Boxing技术,即通过在浮点数编码中预留空间来实现不同类型数据的紧凑存储。每个类型通过4位的itype指针来标识,使得数据的解析与存储变得高效。
对于number数据类型,其值被存储在一个double中,而其他类型如nil、true、false等则利用剩余的空间来标识其类型。这种设计允许LuaJIT在内存中以一种紧凑且高效的方式存储各种数据类型,同时通过简单的位操作就能识别出具体的数据类型。
对于GC对象(如string、table等),LuaJIT通过特定的itype值来区分它们与普通数据类型,以及与值类型(如nil和bool)和轻量级用户数据的差异。通过宏判断,LuaJIT能够快速识别出TValue是否为GC对象,以及具体是哪种类型的GC对象。
在开启LJ_GC模式下,GC对象的地址被存储在TValue的特定字段gcr中,提供位的地址支持。虽然前位用于标识数据类型,但实际使用时仅利用了低位的地址空间,对于大多数实际应用而言,这部分内存已经绰绰有余。
在GCobj数据结构中,通过union的特性实现不同类型对象的共通性与特定性。GChead提供了通用的接口来获取对象的通用信息,而nextgc、marked等字段用于实现垃圾回收机制。通过gct字段,LuaJIT能够将一个GCObj转换为实际的类型对象,进一步增强了内存管理的灵活性。
对于整数类型,默认情况下LuaJIT使用double进行存储以确保精度,但在实际应用中,频繁使用的整数通过宏LJ_DUALNUM启用,以int类型存储,提高了数据处理的效率。此时,TValue的i字段用于保存int值,同时通过位移操作确保了数据的正确存储与解析。
图解Lua分代GC
一直对GC很感兴趣,最近阅读Lua GC相关资料并结合Lua5.4.6源码总结了Lua的分代GC机制。
在Lua中,对象根据年龄被划分为新旧不同阶段。其中,NEW、SURVIVAL属于新对象;OLD、OLD0、OLD1、TOUCHED1、TOUCHED2属于老对象。
对象的颜色表示其状态,分为黑、白、灰三种。黑色代表对象已被完全标记,灰色代表有待标记,白色代表不再被使用的对象。YoungGC通过递归标记灰色对象,清理白色对象。
对象颜色通过mark字段中的三个比特位表示,黑色占一个比特,白色占两个比特,全0表示灰色状态。
使用三色标记方法,对象颜色动态变化,帮助GC准确识别无用对象。
在Lua GC中,对象的管理通过特定的链表结构实现,包含普通无析构函数对象链表、有析构函数对象链表以及灰色对象链表。
新对象经历两次小GC才能成为老对象的机制,旨在确保新对象的生命周期大于一次年轻代GC间隔,避免错误标记。
源码中只标记OLD1年龄态对象的原因是,G_TOUCHED1、G_TOUCHED2、OLD0年龄态对象已经在灰链中。而OLD年龄态在小GC时不进行引用标记。
OLD1年龄态对象已经历两次小GC,理论上属于老对象范畴。但将其直接归并入OLD态会导致SURVIVAL年龄态对象的引用标记问题。
通过上述机制,Lua的分代GC实现了高效而精准的对象管理,降低了内存碎片,提升了程序性能。