标签:gcs lin 大量 多处理器 集中 enable 垃圾回收器 后台 处理器
带着问题去思考!大家好
上次我们讲到GC的一些基础知识,感谢评论的大佬给我指点。
配置参数
关于配置垃圾回收器的方法不是很多,所以建议不要随意去动,垃圾回收器的配置以及调优,很大程度上由硬件配置,可用资源和程序的行为决定。屈指可数的几个参数也是用于控制很高层的行为,主要取决于程序的类型,
工作站模式还是服务器模式?
在垃圾回收默认采用的工作站模式。工作站模式,所有的GC都运行于触发垃圾回收的线程中,优先级(Priority pra????r?ti)也相同。对于单机处理器的计算机而言,工作站模式是唯一选择,配置其他参数也是无效的
服务器模式下,GC会为每个逻辑处理器或处理器核心创建各自专用的线程。这些线程的优先级最高的,但在需要进行 垃圾回收之前会一直保持挂起状态。垃圾回收完成后,这些线程会再次进如休眠状态。
此外,CLR还会为每个处理器创建各自肚子的内存堆,每个处理器堆都包含1个小对象堆和1个LOH。从应用程序角度来看,就只有一个逻辑内存堆。你的代码不清楚对象属于哪一个堆,对象引用会在所有堆之间交叉进行。
多个内存堆的存在会带来一写好处。
1:垃圾回收可以并行进行,每个垃圾回收线程负责回收一个内存堆,这可以让垃圾回收的速度明显快鱼工作站模式
2:某些情况下,内存分配的速度也会更快一些,特别是对LOH而言,因为会在所有内存堆中同时进行份分配。
具体配置
<gcServer enabled="true">
在runtime节点下。
说到底到底用哪个好呢?如果应用程序运行于专为你准备的多处理器主机上,那么选择服务器模式。这样大部分情况,都能让垃圾回收占用的时间降至最低。
如果需要多个托管进行共用一台主机,那么服务器模式的垃圾回收会创建多个高优先级的线程。如果多个应用程序都这么设置,那线程调度就会相互带来负面影响,如果你确定想让同一台主机的多个应用程序使用服务器模式的垃圾回收,还有一种做法,就是让存在竞争关系的应用程序都集中在指定的几个处理器上运行,这样CLR只会为这些处理器创建自己的内存堆。
后台垃圾回收
首先BackgroundGC只会影响第2代内存堆的垃圾回收行为,第0代和第1代的垃圾回收仍会采用前台的垃圾回收,也就是会阻塞所有应用程序的线程。后台垃圾回收由一个专用的第2代堆垃圾回收线程完成,
如果关闭,但不建议
<gcConcurrent enabled="false"/>
低延迟模式
如果一段时间内确保较高的性能,可以通知GC不要执行开销很大的第2代垃圾回收。请根据其他参数把GCSettings.LatencyModel属性赋为以下值之一。
LowLatency---仅适用与工作站模式GC,禁止第2代垃圾回收。
SustainedLowLatency--适用与工作站和服务器模式的GC,禁止第2代完全垃圾回收,但允许第2代后台垃圾回收,必须启用后台垃圾回收。
因为不会再进行碎片整理了,所以这两种参数都会显著增加托管堆的大小,如果你的进程需要大量内存,就应该避免使用这种延迟模式。在即将进入低延迟模式前,最好是能强制执行一次完全垃圾回收,这通过调用GC.Collect即可完成,当代离开低延迟模式后,马上再做一次完全垃圾回收,
以下条件都满足时,才能开启低延迟模式
如何减少内存的分配量
要想减少内存的分配数量,请严格审查没一个对象。
首要规则
其实我们都已经知道,针对垃圾回收器,存在一条基本的高性能编码规则。其实垃圾回收器明显就是按照这条规则进行设计。
只对第0内存堆中的对象进行垃圾回收
简而言之,对象的生存期尽可能短暂,这样垃圾回收器根本就不会去触及它们,或者做不到转瞬即逝,就让对象尽快提升到 第2代内存堆并永远留在哪里,再也不会被回收。这意味着需要一直保存一个堆长久存活对象的引用,通常这也意味要把可重用的对象进行池化(Pooling),特别是LOH中的所有对象。
缩短对象的生命期
减少对象树的深度
我们都知道,GC将会沿着对象引用遍历,在服务器模式GC中,一次会有多个线程同时遍历,你肯定希望尽可能的利用这种并发机制,但如果有某个线程陷入一条很长的嵌套对象链中,那么整个垃圾回收过程就得等整个线程完成工作后才会结束。
减少对象间的引用
如果对象引用了很多其他对象,垃圾收集器对其遍历时就要耗费更多的时间。如果垃圾回收引用的暂时时间较长,往往意味着有大型,复杂的对象间引用关系存在,如果难以确定对象所有的被引用关系,还有一个风险就是何难预测对象的生存期,减少对象引用的复杂度,不仅对提高代码质量有利,而且可以让代码调试和修正性能问题变得更加容易,还需要注意,不同代的内存堆之间的对象引用可能会导致垃圾回收器的低效运行,特别是从老对象中引用新对象的情况,比如第2代内存堆中有个对象包含了对第0代内存对对象的引用,这样每次第0代垃圾回收,总有一部分第2代内存堆中的对象不得不被遍历到。以便确认它们是否还持有堆第0代对象的引用。
标签:gcs lin 大量 多处理器 集中 enable 垃圾回收器 后台 处理器
原文地址:https://www.cnblogs.com/ccaa/p/12571485.html