.net关注GC回收的意义在哪里?

数据的流 2021-01-06 05:04:05
相信很多人面试的时候都聊过GC,关于GC的回收也都看过相关的一些文章,比如:
什么时候发生GC
  1、当应用程序分配新的对象,GC的代的预算大小已经达到阈值,比如GC的第0代已满;
  2、代码主动显式调用System.GC.Collect();
  3、其他特殊情况,比如,windows报告内存不足、CLR卸载AppDomain、CLR关闭,甚至某些极端情况下系统参数设置改变也可能导致GC回收。

这个说法来自于微软相关文章的翻译,关于第1种情况的阈值,解释非常笼统非常抽象,没有给出具体的值、如何配置等等,比如我写一个程序运行中如何知道什么时候达到了阈值触发了回收。

那么问题来了,.net是基于托管的语言,GC的回收触发时机又是非常模糊和不确定,关注GC的意义在哪里?
是否做好非托管资源(文件、数据库连接等)的释放是不是就足够了?
...全文
2172 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
数据的流 2021-01-08
  • 打赏
  • 举报
回复
引用 4 楼 tangyanzhi1111 的回复:
关于阈值这个问题,阈值有阈值的上下限和阈值系数的上下线 第0带的阈值下限位0,上线也为6MB左右 第1代的阈值下限位160KB,上限无限制 第二代的阈值下限为 256kb,上限无限制 第二代大对象阈值下限为3MB,上线无限制 至于系数嘛,由于第0代区分服务器和工作战模式所以分别为(20,10以及9,20) 其余代 上下限以及12代大小对象的分别为(2,7 ---1.2f,1.8f--- 1.25f,4.5f) 由于每次触发一次GC回收都会新计算分配量,分配量是根据系数以及上次分配量来计算,顶值不超过上面的数值。超过了就触发物理内存不足,同样导致再次GC。 具体计算方法如下: float allocation_fraction = (float) (dd_desired_allocation (dd) - dd_gc_new_allocation (dd)) / (float) (dd_desired_allocation (dd));//计算偏移率 cst = min (1.0f, float (out) / float (dd_begin_data_size (dd)));//计算存活率,GC结束后该代存活对象大小/开始前该代存活对象大小 f = surv_to_growth (cst, limit, max_limit); //计算阈值增长系数 if ((allocation_fraction < 0.95) && (allocation_fraction > 0.0))//当偏移率大于0 小于0.95 { // 新分配量阈值= 偏移率* 新分配了阈值 + (1.0 - 偏移率)* 就分配了阈值 new_allocation = (size_t)(allocation_fraction*new_allocation + (1.0-allocation_fraction)*previous_desired_allocation); }
感谢解惑
  • 打赏
  • 举报
回复
有个扫地机器人把你扫垃圾,你非要自己去捡那别人也是拦不住你的
正怒月神 2021-01-07
  • 打赏
  • 举报
回复
GC只是让程序员摆脱大部分手动释放。 因为大多程序员其实管理不好。
andy_wanhl 2021-01-07
  • 打赏
  • 举报
回复
不需要管。非托管注意就行了。
xiaoxiangqing 2021-01-07
  • 打赏
  • 举报
回复
同意5楼的观点
ziqi0716 2021-01-07
  • 打赏
  • 举报
回复
引用 2 楼 数据的流 的回复:
[quote=引用 1 楼 ziqi0716 的回复:].net很少关注,但是如果与非托管代码一起开发就得考虑了.这种非常讨厌,各种恶心
非托管代码不属于GC的一亩三分地,它想管也管不了吧[/quote] 参与过这种项目你就明白了,真的恶心
八爻老骥 2021-01-07
  • 打赏
  • 举报
回复
你又不参与开发.net framework,管GC干什么。每个对象的引用都会有计数器,计数为0的时候就可以当成垃圾回收了,至于什么时候加个真不是上层程序要管的事情。
HerryDong 2021-01-06
  • 打赏
  • 举报
回复
不需要太纠结垃圾自动回收这个东西吧~C#的垃圾自动回收通俗一点理解:你在一个地方扔垃圾,不需要你捡起来扔进垃圾桶,因为会有人定期来打扫。而类似C++这样的语言,自己扔了垃圾(new)必须赶紧自己捡起来扔掉(delete),就是这么个区别。对于非托管的资源,诸如文件流、数据库连接之类的操作,也只需要用using括起来就行了。
江湖评谈 2021-01-06
  • 打赏
  • 举报
回复
关于阈值这个问题,阈值有阈值的上下限和阈值系数的上下线 第0带的阈值下限位0,上线也为6MB左右 第1代的阈值下限位160KB,上限无限制 第二代的阈值下限为 256kb,上限无限制 第二代大对象阈值下限为3MB,上线无限制 至于系数嘛,由于第0代区分服务器和工作战模式所以分别为(20,10以及9,20) 其余代 上下限以及12代大小对象的分别为(2,7 ---1.2f,1.8f--- 1.25f,4.5f) 由于每次触发一次GC回收都会新计算分配量,分配量是根据系数以及上次分配量来计算,顶值不超过上面的数值。超过了就触发物理内存不足,同样导致再次GC。 具体计算方法如下: float allocation_fraction = (float) (dd_desired_allocation (dd) - dd_gc_new_allocation (dd)) / (float) (dd_desired_allocation (dd));//计算偏移率 cst = min (1.0f, float (out) / float (dd_begin_data_size (dd)));//计算存活率,GC结束后该代存活对象大小/开始前该代存活对象大小 f = surv_to_growth (cst, limit, max_limit); //计算阈值增长系数 if ((allocation_fraction < 0.95) && (allocation_fraction > 0.0))//当偏移率大于0 小于0.95 { // 新分配量阈值= 偏移率* 新分配了阈值 + (1.0 - 偏移率)* 就分配了阈值 new_allocation = (size_t)(allocation_fraction*new_allocation + (1.0-allocation_fraction)*previous_desired_allocation); }
wanghui0380 2021-01-06
  • 打赏
  • 举报
回复
就跟你装行车记录仪的作用一样。虽然平时他几乎没啥作用。但真出事的时候,你就知道他有用了 和那个园子不同,其实真正开发是不管的。也就是那个园子的人喜欢吹吹NB,觉得会gc了就能把HR和面试管给侃晕了 其实真实的情况是,如果我知道门不够宽(内存不够),那么你能做的只有两件事情 1.排好队,别插队,别争抢 2.每个人都给我快速过去,别堵门。(大任务都给我拆小了,能快速平稳过去,比你天天想着怎么造个更结实的门有用) so,你瞧我们讨论GC么,那些个吹NB说一个gc如何如何血案的,其实把原因很简单,他们只想怎么把门弄结实了,结果是你在结实的门,也经不住疯狂的冲撞和某个人就是不过去,他就堵着门。ok,血案发生,so,继续找个更结实的门去把
数据的流 2021-01-06
  • 打赏
  • 举报
回复
引用 1 楼 ziqi0716 的回复:
.net很少关注,但是如果与非托管代码一起开发就得考虑了.这种非常讨厌,各种恶心
非托管代码不属于GC的一亩三分地,它想管也管不了吧
ziqi0716 2021-01-06
  • 打赏
  • 举报
回复
.net很少关注,但是如果与非托管代码一起开发就得考虑了.这种非常讨厌,各种恶心

111,066

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧