引言

GC 作为CLR的垃圾回收器,让程序员可以把更多的关注度放在业务上而不是垃圾回收(内存回收)上。其实很多语言也有类似的东东,

如Java也有JIT 等等

GC基本概念

  • 垃圾回收机制的算法有好多种,GC为Mark-Sweep算法。
  • GC中分为三代,来优化管理不同生命周期的对象。
  • 大部分的对象在Gen0就死掉了。
  • Gen0 和Gen 1 又叫作ephemeral generations (短命代,个人翻译意见 )
  • 大于85,000bytes的对象会被直接分配到Large object heap上,且在Gen2回收时才会被回收。

GC回收时机

  1. 系统内存不足
  2. Gen0 没有足够的空间需要申请新的空间(应该是segment)
  3. 手动条用GC.Collect()

GC步骤

当进行一次垃圾回收操作时,会分三个步骤进行:
1. 先假设所有对象都是垃圾;
2. 标记出正在使用的对象; (会先找GC Roots,然后遍历GC Heap上的每个对象,生成一个对象List)
标记依据:
     a. 被变量引用的对象,仍然在作用域中。
     比如某个类中的某个方法,方法执行了一半,如果此时发生垃圾回收,那么方法块中的变量都在作用域中,那么它们都会被标记为正在使用。
     b. 被另一个对象引用的对象,仍在使用中。
3. 压缩:释放第二步中未标记的对象(不再使用,即“垃圾”)并将使用中的对象转移到连续的内存块中。
只要垃圾回收器释放了能释放的对象,它就会压缩剩余的对象,把它们都移回堆的端部,再一次形成一个连续的块。(这里其实有个更新引用或者说指针的操作)

GC处理Finalizalbe对象工作原理

上图假设是新创建对象为Gen0 代的且为Finalizable的对象,首次就会被回收(如局部的且<85,000bytes的对象)。

实现 Finalize 方法或析构函数对性能可能会有负面影响,因此应避免不必要地使用它们。用 Finalize 方法回收对象使用的内存需要至少两次垃圾回收。当垃圾回收器执行回收时,它只回收没有终结器的不可访问对象的内存。这时,它不能回收具有终结器的不可访问对象。它改为将这些对象的项从终止队列中移除并将它们放置在标为准备终止的对象列表中。该列表中的项指向托管堆中准备被调用其终止代码的对象。垃圾回收器为此列表中的对象调用 Finalize 方法,然后,将这些项从列表中移除。后来的垃圾回收将确定终止的对象确实是垃圾,因为标为准备终止对象的列表中的项不再指向它们。在后来的垃圾回收中,实际上回收了对象的内存。

GC分类

从工作模式角度来看:

两大类:WorkStation GC Server GC

分类依据:

WorkStation GC 是默认的工作方式,如果你是单处理器的机器,那么这是你唯一的选择,并且及时你配置了Concurrent选项为True,也不会生效。

Server GC 在多处理器的机器上才会出现,且默认出现在Aps.net寄存服务中。他会为每个处理器都创建一个GC Heap,并且会并行执行回收操作。该模式的GC可以最大化吞吐量和较好的收缩性(4处理器+)

<configuration>
  <runtime>
    <gcServer enabled="true" />
  </runtime>
</configuration>

可以通过以上配置方式或者通过native code 类指定GC 工作模式

HRESULT CorBindToRuntimeEx( LPWSTR pwszVersion,
  LPWSTR pwszBuildFlavor, // use “svr” for server mode,
  // “wks” or NULL for workstation
  DWORD flags,
  REFCLSID rclsid,
  REFIID riid,
  LPVOID* ppv );

下表为GC为GC heap向系统申请时的基本单位Segment的默认值,注意是默认值,这些值会随着程序的实际执行情况,GC动态调整。这里了解下即可,另外正是由于有segment的概念所以回出现内存碎片的问题,所以GC在垃圾回收过程中会进行内存整理,以减少内存碎片,提高内存使用率。

 

32-bit

64-bit

Workstation GC

16 MB

256 MB

Server GC

64 MB

4 GB

Server GC with > 4 logical CPUs

32 MB

2 GB

Server GC with > 8 logical CPUs

16 MB

1 GB

从工作方式,工作侧重点和实现上来看:

两类:Foreground GC,Concurrent GC | BackGround GC(侧重于Gen2 GC性能优化,正常情况Gen0 ,Gen1的速度都比较快)

Foreground GC工作的时候绝对是.net 程序要向系统申请分配Gc Heap空间啦,所以它的优先级最高。一旦它运行,其他所有线程都会被挂起来。

通过配置文件开启或者关闭并发和后台模式,(同一个配置项)

<configuration>
<runtime>
   <gcConcurrent enabled="false" />
</runtime>
</configuration

In workstation or server garbage collection, you can enable concurrent garbage collection , which enables threads to run concurrently with a dedicated thread that performs the garbage collection for most of the duration of the collection. This option affects only garbage collections in generation 2; generations 0 and 1 are always non-concurrent because they finish very fast.


Server GC 和Workstation GC都可以开启并发GC。在GC回收的过程中大部分时间用户线程可以并发运行。但这中效果只能影响到2带GC的过程,因为0代1代的时间太短了。

  Concurrent WS Non-Concurrent WS BackGround WS
(替代并发)
Server GC Server GC Background(替代并发)
出现时间 .net 1+ .net 1+<x<.net.4 .net 4+ .net 1+ .net 4.5.1+
设计目标 在吞吐量和界面相应速度上寻找平衡点 最大化吞吐量 在WS的设计基础上,优化gen2 GC性能 多处理器机器上使用多线程处理相同类型的请求以便最大化服务程序吞吐量 优化gen2 GC性能
GC Heap数量 1 1 1 1 per processor (HT aware) 1 per processor (HT aware)
GC threads 分配空间的线程会触发GC, 分配空间的线程会触发GC线程   每个处理器都有一个专职的GC线程 每个处理器都有一个专职的GC background线程
GC线程优先权 和工作线程具有相同的优先权 和工作线程具有相同的优先权 background GC线程与工作线程有相同优先级,但都低于前台GC线程 THREAD_PRIORITY_HIGHEST background GC线程与工作线程有相同优先级,但都低于前台GC线程
工作线程(非GC线程) GC工作过程中短暂多次挂起 GC工作过程中一直被挂起 GC工作过程中短暂多次挂起,较并发性能更加(针对Gen2的) GC工作过程中会被挂起 GC工作过程中短暂多次挂起,较并发性能更加(针对Gen2的)
ephemeral generation 的前台GC工作时会挂起其他所有线程
配置方式 <gcConcurrent enabled="true"> <gcConcurrent enabled="false"> <gcConcurrent enabled="false"> <gcServer enabled="true"> <gcConcurrent enabled="false">
是否会超时       不会

----------------------------------------------------------------------------------------------

Workstation GC

-------------------------------------------------------------------------------------------------

Server garbage collection

-------------------------------------------------------------------------------------------------


Concurrent garbage collection

-------------------------------------------------------------------------------------------------

Background workstation garbage collection

-------------------------------------------------------------------------------------------------

Background server garbage collection

-------------------------------------------------------------------------------------------------

其他相关

编程的内存模型中我们会接触到“堆”和“栈”两个部分。每个线程都有自己的栈,但共享堆(当然不是直接跨线程访问的意思,只能理解为共存在堆上)。

性能计数

What is the cost of a garbage collection? How can I keep this cost at a minimum?

You can measure the GC cost for your application with a few different counters. Remember that all of these counters are updated at the end of a collection which means that if you use averages they may not be valid after a long time of inactivity.

.NET CLR Memory\% time in GC - This counter measures the amount of CPU time you spend in GC and it is calculated as (CPU time for GC/CPU time since last GC)

.NET CLR Memory\# Induced GC – This is the number of garbage collections that have occurred as a result of someone calling GC.Collect(). Ideally this should be 0 since inducing full collections means that you spend more time in the GC, and also because the GC continuously adapts itself to the allocation patterns in the application, and performing manual GCs skews this optimization.

.NET CLR Memory\# Gen X collections – This counter displays the amount of collections that have been performed for a given generation. Since the cost of gen 2 collections is high compared to Gen 1 and Gen 0 you want to have as few Gen 2 collections per Gen 1 and Gen 0 collections as possible. A ratio of 1:10:100 is pretty good.

The most common causes for high CPU in GC or a high number of Gen 2 collections compared to 1 and 0 is high allocation of large objects and letting objects survive multiple generations because of improper use of finalizers or because finalizable objects are not disposed of correctly in the application.

参考

Finding garbage

.NET垃圾回收 – 原理浅析

How does the GC work and what are the sizes of the different generations?

垃圾回收

C#技术漫谈之垃圾回收机制(GC)

托管堆与垃圾收集

关于CLR内存管理一些深层次的讨论

http://blogs.msdn.com/maoni/archive/2004/06/15/156626.aspx

http://blogs.msdn.com/maoni/archive/2004/09/25/234273.aspx

垃圾回收翻译系列(√)

不得不知的CLR中的GC的更多相关文章

  1. 在 C# CLR 中学习 C++ 之了解 extern

    一:背景 在 CLR 源码中有很多的 extern 和 extern "C" 这样的关键词,比如下面这些代码: extern size_t gc_global_mechanisms ...

  2. CLR中的程序集加载

    CLR中的程序集加载 本次来讨论一下基于.net平台的CLR中的程序集加载的机制: [注:由于.net已经开源,可利用vs2015查看c#源码的具体实现] 在运行时,JIT编译器利用程序集的TypeR ...

  3. CLR中的垃圾回收机制

    CLR中采用代(generation)来作为其垃圾回收的一种机制,其唯一的目的是提升程序的性能.基予代的垃圾回收器有以下假设: ·对象越新,其生存周期越短. ·对象越老,其生存周期越长. ·回收堆的一 ...

  4. Unity中的GC以及优化

    [简介] 常见的 Unity GC 知识点总结出来的思维导图 Unity 官方文档,正巧在博客园发现了已经有位大神(zblade)把原文翻译出来了,而且质量很高~,译文地址 在这里.下面我就可耻地把译 ...

  5. 浅谈Unity中的GC以及优化

    介绍: 在游戏运行的时候,数据主要存储在内存中,当游戏的数据不在需要的时候,存储当前数据的内存就可以被回收再次使用.内存垃圾是指当前废弃数据所占用的内存,垃圾回收(GC)是指将废弃的内存重新回收再次使 ...

  6. [C#] 类型学习笔记一:CLR中的类型,装箱和拆箱

    在学习.NET的时候,因为一些疑问,让我打算把.NET的类型篇做一个总结.总结以三篇博文的形式呈现. 这篇博文,作为三篇博文的第一篇,主要探讨了.NET Framework中的基本类型,以及这些类型一 ...

  7. 警惕C#事件使用过程中的GC陷阱

    关于C#中的事件,园里已经有大量的文章对其内在实现做过剖析,如果还不甚了解的可以阅读这篇文章 通过Demo来细看C#事件的内在机制 虽然比较早,但非常清楚地展示了事件的内部机制,总结一下就是 1.事件 ...

  8. 如何诊断RAC系统中的'gc cr multi block request'?

    'gc cr multi block request' 是RAC数据库上比较常见的一种等待事件,在RAC 上进行全表扫描(Full Table Scan)或者全索引扫描(Index Fast Full ...

  9. 如何查看子线程中的GC Alloc

    1)如何查看子线程中的GC Alloc2)Build时,提示安卓NDK异常3)如何获得ParticleSystem产生的三角形数量4)关于图片通道的问题5)GPUSkinning导致模型动画不平滑 M ...

随机推荐

  1. 奇异值分解(SVD)原理与在降维中的应用

    奇异值分解(Singular Value Decomposition,以下简称SVD)是在机器学习领域广泛应用的算法,它不光可以用于降维算法中的特征分解,还可以用于推荐系统,以及自然语言处理等领域.是 ...

  2. 传播正能量——做一个快乐的程序员

    引子 今天在博客园看到施瓦小辛格的文章我们搞开发的为什么会感觉到累,顿时有感而发.自己本来不擅长写文章,更不擅长写这种非技术性的文章,但是在思绪喷薄之际,还是止不住有很多话要说.针对从客观上说&quo ...

  3. Ubuntu 14.04中Elasticsearch集群配置

    Ubuntu 14.04中Elasticsearch集群配置 前言:本文可用于elasticsearch集群搭建参考.细分为elasticsearch.yml配置和系统配置 达到的目的:各台机器配置成 ...

  4. WPF做12306验证码点击效果

    一.效果 和12306是一样的,运行一张图上点击多个位置,横线以上和左边框还有有边框位置不允许点击,点击按钮输出坐标集合,也就是12306登陆的时候,需要向后台传递的参数. 二.实现思路 1.获取验证 ...

  5. InnoDB体系结构学习笔记

    后台线程 Master Thread 核心的后台线程,主要负责将缓冲池的数据异步刷新到磁盘,保证数据的一致性,包括(脏页的刷新).合并插入缓冲.(UNDO页的回收)等 IO Thread 4个writ ...

  6. python程序生成平均脸

    简介 项目代码https://github.com/LiuRoy/pokerface 原文链接http://www.cnblogs.com/lrysjtu/p/5492547.html 写这个项目的本 ...

  7. WebLogic的安装和配置以及MyEclipse中配置WebLogic

    WebLogic 中间件: 是基础软件的一大类,属于可复用软件的范畴,顾名思义,中间件属于操作系统软件与应用软件的中间,比如:JDK,框架,weblogic. weblogic与tomcat区别 : ...

  8. SQLServer 各版本区别

    SQLServer 2012 新特性 通过AlwaysOn实现各种高可用级别 通过列存储索引技术实现超快速的查询,其中星型链接查询及相似查询的性能提升幅度可高达100倍,同时支持超快速的全文查询 通过 ...

  9. PMON failed to acquire latch, see PMON dump

    前几天,一台Oracle数据库(Oracle Database 10g Release 10.2.0.4.0 - 64bit Production)监控出现"PMON failed to a ...

  10. windows 7(32/64位)GHO安装指南(系统安装篇)~重点哦!!~~~~

    经过了前三篇的铺垫,我们终于来到了最重要的部分~~如果没看过前几篇的小伙伴们,可以出门右转~~用十几分钟回顾一下~~然后在看这篇会感觉不一样的~~~~ 下面让我们来正式开始吧 我们进入大白菜的桌面是酱 ...