浅谈c#和lua的gc

更新时间:2023-07-12 23:13:52 阅读: 评论:0

浅谈c#和lua的gc
前提:
本⽂参考和借鉴相关博客,相关版权归其所有,我只是做⼀个归纳整理,所以本⽂没有任何版权
参考⽂献和书籍:
CLR和.Net对象⽣存周期:
c#Finalize 和Dispo的区别:
《Lua设计与实现》——codedump 著
⼀、概要
本次对常见使⽤的c#和lua语⾔的gc操作原理和过程进⾏⼀次归类整理,加深对语⾔的理解,也为后续写出更优性能更好的代码做相关知识储备。
维吾尔族图片⼆、c#的垃圾回收
2.1 基本概念
1. CLR
CLR: Common Language Runtime, 公共语⾔运⾏时,是⼀种可以⽀持多种语⾔的运⾏时,其基本的核⼼功能包含:
内存管理
程序集加载和卸载
类型安全
异常处理
线程同步
2. 托管模块
CLR并不关⼼是使⽤何种语⾔进⾏编程开发,只要编译器是⾯向CLR⽽进⾏编译的即可,这个中间的结果,就是IL(Intermediate Language), 最终⾯向CLR编译得到的结果是:IL语句以及托管数据(元数据)组成的托管模块
PS:
元数据: 元数据的本质就是⼀种描述数据的数据
借鉴相关⽂章的图,其基本的过程为:
托管模块的基本组成:
PE32/PE32+(64位)
CLR头
元数据
IL代码(托管代码)
3. 引⽤类型和值类型
这部分略过,基本都有相关的认识,本质是看其分配的内存位于内存堆上还是栈上。
每个进程会分配⼀个对应的进程堆,这就是我们常说的程序内存申请区域,不同进程是不会有交叉的。在堆上还是在栈上进⾏内存分配,是没有速度差异的,都很快。
武当派创始人4. 垃圾回收器(Garbage Collector)
在CLR中的⾃动内存管理,就会使⽤垃圾回收器来执⾏内存管理,其会定时执⾏,或者在申请内存分配是发现内存不⾜时触发执⾏,也可以⼿动触发执⾏(System.GC.Collect)
垃圾回收的⼏种基本算法
标记清除算法(Mark-Sweep)
关键点是,清除后,并不会执⾏内存的压缩
复制算法(Copying) 内存等额划分,每次执⾏垃圾回收后,拷贝不被回收的内存到没有被使⽤的内存块,⾃带内存压缩,弊端是内存浪费⼤(每次只能使⽤部分,预留部分给拷贝使⽤)
标记整理算法(Mark-Compact)
关键点,清除后,会执⾏内存压缩,不会有内存碎⽚
分代收集算法(Generational Collection)
对内存对象进⾏分代标记,避免全量垃圾回收带来的性能消耗。下⽂会详细讲解。
2.2 垃圾回收模型
1. 垃圾回收的⽬的
缘由:内存是有限的,为了避免内存溢出,需要清理⽆效内存
2. 触发时机
申请分配内存时内存不⾜(本⾝不⾜或者内存碎⽚过多没有⾜够⼤⼩的内存⽚)
强制调⽤System.GC.Collect
CLR卸载应⽤程序域(AppDomain)
CLR正在关闭(后⾯2种在进程运⾏时不会触发)
3. 垃圾回收的流程
GC准备阶段
雅思写作
暂停进程中的所有线程,避免线程在CLR检测根期间访问堆内存
公司会议制度
GC的标记阶段
⾸先,会默认托管堆上所有的对象都是垃圾(可回收对象),然后开始遍历根对象并构建⼀个由所有和根对象之间有引⽤关系的对象构成的对象图,然后GC会挨个遍历根对象和其引⽤对象,如果根对象没有任何引⽤对象(null)GC会忽略该根对象。
对于含有引⽤对象的根对象以及其引⽤对象,GC将其纳⼊对象图中,如果发现已经处于对象图中,则换⼀个路径遍历,避免⽆限循环。
千什么一律
PS:所有的全局和静态对象指针是应⽤程序的根对象。
大嗓门妈妈
垃圾回收阶段完成遍历操作后,对于没有被纳⼊对象图中的对象,执⾏清理操作
碎⽚整理阶段
如果垃圾回收算法包含这个阶段,则会对剩下的保留的对象进⾏⼀次内存整理,重新归类到堆内存中,相应的引⽤地址也会对应的整理,避免内存碎⽚的产⽣。
4. 分代垃圾回收的过程
分代的基本设计思路:
对象越新,⽣命周期越短,反之也成⽴
回收托管堆的⼀部分,性能和速度由于回收整个托管堆基本的分代: 0/1/2:
0代: 从未被标记为回收的新分配对象
1代: 上⼀次垃圾回收中没有被回收的对象
2代: 在⼀次以上的垃圾回收后任然未被回收的对象
操作图解释分代的过程:
低⼀代的GC触发,移动到⾼⼀代后,未必会触发⾼⼀代的GC,只有⾼⼀代的内存不⾜时才会触发⾼⼀代的GC
民兵整组
不同代的⾃动GC频率是可以设置的,⼀般0:1:2的频率为100:10:1
2.3 ⾮托管对象的回收
对于⾮托管对象的管理,不受CLR的⾃动内存管理操作,这部分需要借鉴CLR的⾃动管理或者⼿动执⾏内存回收,这就是两种⾮托管对象的管理⽅式: Finalize 和Dispo
小酥肉蒸碗
⾮托管资源: 原始的操作系统⽂件句柄,原始的⾮托管数据库连接,⾮托管内存或资源
1.Finalize
System.Object定义了Finalize()虚⽅法,不能⽤override重写,其写法类似c++的析构函数:
class Finalization{

本文发布于:2023-07-12 23:13:52,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/89/1079048.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:内存   回收   对象   托管   垃圾
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图