工具出现挂死问题,巡检IIS发现如下异常日志html
现网系统日志:安全
事件类型: 错误服务器
事件来源: .NET Runtime架构
描述:并发
Application: DiyRingSet30Tool.exe工具
Framework Version: v4.0.30319性能
Description: The process was terminated due to an internal error in the .NET Runtime at IP 791F7E06 (79140000) with exit code 80131506.优化
说明:此日志能够经过“开始”-“全部程序”-“管理工具”-“事件查看器”-“应用程序”,观察类型为错误或者警告的日志,通常出现错误日志都是应用程序错误致使的,请引发重视网站
在工具的配置文件中新增如下红色的配置节点内容spa
<configuration>
<runtime>
<gcConcurrent enabled="false"/>
</runtime>
</configuration>
缘由:正在引用的对象被取消引用由垃圾回收器在公共语言运行库4(CLR4)中发生的问题。所以,垃圾回收或应用程序尝试访问已发布的对象的过程当中发生访问冲突。
垃圾回收器可自行优化而且适用于多种方案。 可基于工做负荷的特征使用配置文件来设置垃圾回收的类型。 CLR垃圾回收能够作内存移动也能够不作移动。不作移动时也称为“清扫”,清扫的代价要比作压缩的代价低一些,由于他不须要复制移动内存。CLR 提供了如下类型的垃圾回收:
1)工做站模式:关闭并发的工做站GC、开启并发的工做站GC
2)服务器模式:服务器GC
工做站垃圾回收,用于全部客户端工做站和独立 PC。 这是运行时配置架构中的 <gcServer> 元素的默认设置。既能够是并发的,也能够是非并发的。 并发垃圾回收使托管线程可以在垃圾回收期间继续操做。从 .NET Framework 4 开始,后台垃圾回收取代了并发垃圾回收。
服务器垃圾回收,用于须要高吞吐量和可伸缩性的服务器应用程序。 服务器垃圾回收既能够是非并发或后台运行。
1) 关闭并发的工做站GC为高性能服务器的高吞吐量作了优化。咱们在垃圾回收时根据分配和复活模式作动态调优所以能够程序运行时自动调优GC的工做效率。
2) 开启并发的工做站GC是为要求精确响应时间的交互式应用程序设计的。开启并发使垃圾回收形成的工做进程暂停时间缩短。 这个目的是用一些内存和CPU换来的,所以在这种模式下垃圾回收须要作的工做略多一点须要的回收时间会略长一些。
3) 服务器GC,从名字上咱们能够看出这种工做模式是为服务器应用程序设计的;典型的场景是你有一个工做线程池这些线程作着类似的处理。例如:作处理一样的请求或者处理相同类型的事务。全部的线程使用几乎相同的分配模式。服务器GC是为要求高吞吐量的和高扩展性的多处理器服务器设计的
工做站模式(workstation mode) 。
1)这种模式下GC假设机器上运行的其余应用程序对CPU资源要求不高,并发模式是默认的工做站模式,该模式下垃圾回收器分配一个额外的后台线程在应用程序运行时并发回收对象。一个线程由于分配对象形成第0代超出预算时,垃圾回收器挂起全部线程(不会挂起运行本机代码的线程、并发模式容许托管线程在回收期间运行),判断须要回收哪些代,若是须要回收第2代,就会增长第0代的大小。而后应用程序恢复执行。
2)回收发生在触发垃圾回收的用户线程上,并保留相同优先级。 由于用户线程一般以普通优先级运行,因此垃圾回收器(在普通优先级线程上运行)必须与其余线程竞争 CPU 时间。
3)工做站垃圾回收始终用在只有一个处理器的计算机上,而无论 <gcServer> 设置如何。 若是你指定服务器垃圾回收,则 CLR 会使用工做站垃圾回收,并禁用并发。
服务器模式 (servermode)。
1)这种模式下GC假设机器上没有运行其余应用程序,全部的CPU均可以用来进行垃圾回收操做。在这种状况下虚拟内存按照CPU数量划分区域分开对待,每一个CPU上都运行一个GC线程负责回收本身的区域。 为每一个 CPU 提供一个用于执行垃圾回收的一个堆和专用线程,并将同时回收这些堆。 每一个堆都包含一个小对象堆和一个大对象堆,而且全部的堆均可由用户代码访问。不一样堆上的对象能够相互引用。
2)回收发生在以 THREAD_PRIORITY_HIGHEST 优先级运行的多个专用线程上。
3)由于多个垃圾回收线程一块儿工做,因此对于相同大小的堆,服务器垃圾回收比工做站垃圾回收更快一些。
4)服务器垃圾回收一般具备更大的段。
5)服务器垃圾回收会占用大量资源。 例如,若是在一台具备 4 个处理器的计算机上运行了 12 个进程,则在它们都使用服务器垃圾回收的状况下,将有 48 个专用垃圾回收线程。 在高内存加载的状况下,若是全部进程开始执行垃圾回收,则垃圾回收器将要计划 48 个线程。
并发垃圾回收
让咱们从关闭并发的工做站GC提及,其执行流程以下:
1) 一个托管进程作内存分配
2) 分配完全部可用的内存
3) 触发了垃圾回收,垃圾回收操做在作分配的线程上运行
4) GC调用SuspendEE来挂起全部的托管线程
5) GC开始工做
6) GC调用RestartEE来重启工做托管进程
7) 托管进程继续运行
图:演示了在单独的专用线程上执行的并发垃圾回收
你能够看到在第5步中全部的托管线程都中止执行来等待垃圾回收完成工做。SuspendEE不会挂起本地线程(native threads)。
在开启并发垃圾回收(Concurrent GC)时,最大的差别是挂起和重启。并发垃圾回收经过最大程度地减小因回收引发的暂停,使交互应用程序可以更快地响应。 在运行并发垃圾回收线程的大多数时间,托管线程能够在回收期间继续运行。 这意味着并发GC暂停时间很是少。
所以开启并发的垃圾回收会尽量少的执行垃圾回收,执行时间也很是短。在剩余的时间中若是须要托管线程能够运行和分配内存。开启并发时咱们会在开始时给0代一个很大的分配预算来保证垃圾回收运行期间有足够的空间分配对象。(GC中的每一代都有一个“分配预算”的概念。每一代的“分配预算”在运行时是动态调整的。由于咱们常常在0代上作分配,你能够想象0代预算超支了,这样就会触发垃圾回收。这里的预算和GC堆的段大小彻底不是一回事,预算比段大小要小得多。)
尽管如此,若是在并发回收运行中托管线程须要分配过多的内存,线程也会被堵塞直到回收完成。(在并发垃圾回收期间在堆上为小对象分配空间的能力受到在并发垃圾回收启动时临时段上保留的对象的限制。 一旦到达临时段的末尾,将必须等待并发垃圾回收完成,同时将挂起须要执行小对象分配的托管线程。)
在并发垃圾回收中,容许托管的线程在回收期间运行,记住0代和1代回收很是快,因此此选项只影响2代回收,不影响0代和1代,即在作0,1代回收时是不会作并发回收的。只是在2代回收时才会并发回收。
并发垃圾回收具备一个稍微大点的工做集(与非并发垃圾回收相比),这是由于你能够在并发回收期间分配对象。 可是,这会影响性能,缘由是分配的对象将会成为你的工做集的一部分。 实质上,并发垃圾回收会牺牲一些 CPU 和内存来换取更短的暂停。
后台工做站垃圾回收
后台垃圾回收只在 .NET Framework 4 及更高版本中可用。 在 .NET Framework 4 中,仅支持工做站垃圾回收。 从 .NET Framework 4.5 开始,后台垃圾回收可用于工做站和服务器垃圾回收。
图:对工做站上的独立专用线程执行的后台垃圾回收
后台垃圾回收期间对暂时代的回收称为前台垃圾回收。 发生前台垃圾回收时,全部托管线程都将被挂起。当后台垃圾回收正在进行而且你已在第 0 代中分配了足够的对象时,CLR 将执行第 0 代或第 1 代前台垃圾回收。 专用的后台垃圾回收线程将在常见的安全点上进行检查以肯定是否存在对前台垃圾回收的请求。 若是存在,则后台回收将挂起自身以便前台垃圾回收能够发生。 在前台垃圾回收完成以后,专用的后台垃圾回收线程和用户线程将继续。
在后台垃圾回收中,在进行第 2 代回收的过程当中,将会根据须要收集暂时代(第 0 代和第 1 代)。
后台垃圾回收没法设置;它会自动运行并启用并发垃圾回收。 后台垃圾回收是对并发垃圾回收的替代。 与并发垃圾回收同样,后台垃圾回收是在一个专用线程上执行的而且只适用于第 2 代回收。
后台垃圾回收能够消除并发垃圾回收所带来的分配限制,由于在后台垃圾回收期间,可发生暂时垃圾回收。 这意味着,后台垃圾回收能够移除暂时代中的死对象,并且还能够在第 1 代垃圾回收期间根据须要展开堆。
后台服务器垃圾回收
服务器垃圾回收,这种模式和工做站模式彻底不一样。咱们会为每个CPU建立一个回收线程。垃圾回收在这些线程上执行而不是在分配线程上,其工做流程以下:
1. 一个托管线程作回收
2. 分配达到阀值
3. 给GC线程发信号,让GC线程作垃圾回收,等待回收结束
4. GC线程运行,结束时发出回收完成的信号(在回收过程当中,全部的托管线程会像工做站模式中同样被挂起)
5. 托管线程收到信号从新开始运行
从 .NET Framework 4.5 开始,后台服务器垃圾回收是服务器垃圾回收的默认模式。 若要选择此模式,请在运行时配置架构中将 <gcServer> 元素的 enabled 特性设置为true。 此模式与后台工做站垃圾回收具备相似功能,但有一些不一样之处。 后台工做区域垃圾回收使用一个专用的后台垃圾回收线程,然后台服务器垃圾回收使用多个线程,一般一个专用的线程用于一台逻辑处理器。 不一样于工做站后台垃圾回收线程,这些线程不会超时。
图:对服务器上的独立专用线程执行的后台垃圾回收。
要关闭并发回收,在配置文件中添加下面配置项:
<configuration>
<runtime>
<gcConcurrent enabled="false"/>
</runtime>
</configuration>
要使用服务器GC,使用下面配置:
<configuration>
<runtime>
<gcServer enabled=“true"/>
</runtime>
</configuration>
1)若是你在写一个独立的托管程序而且没有作任何配置,默认状况下CLR 将运行工做站垃圾回收并启用并发垃圾回收。 对于单处理器计算机和多处理器计算机都是如此。这会下降性能
2)若是应用程序是单线程而且涉及大量的用户交互,请开启并发垃圾回收,即不须要在配置文件中修改回收方式,便于应用程序不会由于执行垃圾回收而暂停
3)若是你的程序在宿主程序中运行,宿主可能会为程序选择GC的工做模式。
4)若是运行应用程序的数百个实例,请考虑使用工做站垃圾回收并禁用并发垃圾回收。 这能够减小上下文切换,从而提升性能。
5)并发回收是为了给用户更好的交互体验,适合客户端应用程序,可是同时要注意并发回收对性能有损害,使用更多地内存。
6)若要在运行多个进程时提升性能,请禁用并发垃圾回收。
7)在工做站或服务器垃圾回收中,你能够启用并发垃圾回收,以便在大多数回收期间,让各线程与执行垃圾回收的专用线程并发运行。 此选项只影响第 2 代中的垃圾回收;第 0 代和第 1 代中的垃圾回收始终是非并发的,由于它们完成的速度很是快。
1)http://q.cnblogs.com/q/45625/
2)http://msdn.microsoft.com/zh-cn/library/at1stbec.aspx
3)http://www.cnblogs.com/yukaizhao/archive/2011/11/29/use-gc-effective-2.html
4)http://technet.microsoft.com/zh-CN/library/ee851764
5)http://blog.csdn.net/directionofear/article/details/8034133
6)http://msdn.microsoft.com/zh-cn/library/ee787088(v=vs.110).aspx