一起谈.NET技术,.Net Discovery系列-深入理解平台机制与性能影响(上)

  转眼间《.Net Discovery》系列文章已经推出1年了,本文为该系列的第10-13篇文章,在本文中将对以前所讲的.Net平台知识做一个小小的总结与机制分析,引出并重点介绍这些机制对程序性能的影响与改进建议。

  本文将分为四部分,分别讲述了:垃圾回收机制、即时编译机制、异常处理机制、字符串驻驻留机制的原理与性能改进建议。

  《.Net Discovery》系列的每篇文章撰写耗时都在2天以上,转载时麻烦著名作者Aicken(李鸣),并且未经作者同意,禁止一切商业用途!

  一.关于垃圾回收机制●

  机制分析垃圾收集器是.Net平台的一个特性,它自动回收托管堆上不再使用的对象,及时清理内存,这一切都是对开发人员透明的,当然你也可以手动把它召唤出来,它的本质就是跟踪所有被引用到的对象,整理对象不再被引用的对象,回收相应的内存。垃圾收集机制采用标记与清除(Mark Sweep)算法来完成上述任务,整个过程分为两步:

  Step 1.Mark-Sweep :从应用程序的root出发,利用相互引用关系,遍历其在Heap上动态分配的所有对象,指明需要回收的对象,标记出那些存活的对象,予以标记。

  Step 2.Compact: 对内存中存活的对象进行移动,修改它们的指针,使之在内存中连续,这样空闲的内存也就连续了,即完成了内存释放工作,也解决了内存碎片问题,这个过程也可以成为指针的压缩。垃圾收集器一般将托管堆中的对象分为3代,这可以通过调用GC.MaxGeneration得知,对象按照存在时间长短进行分代,最短的分在第0代,最长的分在第2代,第2代中的对象往往是比较大的,第二代空间被称作Large Object Heap,对于2代对象的回收,与第0、1代回收方式相比最大的不同在于,没有了指针移动的压缩过程。如下图,第一次GC时,左边第一列A-F表示内存中的对象,位于浅蓝色 区域,经过Mark后,ACDF标记为可用,Sweep过程清除了BE,Compact过程移动了ACDF,使之位于连续存储区域中;第二次使用绿色做标记;第三次GC使用蓝色表示标记;可以看出第三次GC过程没有了指针移动的压缩过程。

图1 对象的回收

  ●性能影响分析这个过程看起来有点复杂,的确垃圾收集器的启动是会占用一些CPU时间,从而影响系统的性能,但这种影响很有限,并且这些损失是有所值的。

  1.垃圾收集器并不是没有规律的启动,而是当代龄达到一定触发条件时启动,而且垃圾收集器只是移动代龄较低的1、2代的资源,并不会移动LOH中的对象。这就在一定程度上避免了GC长时间锁定线程导致的性能损失。

  2.GC有三种不同的工作模式,适用于不同环境的情况,并不是所有环境都是使用挂起-查找与标记-压缩-恢复 的流程。Workstation GC with Concurrent模式可以第0、1代的收集仍然是要暂时挂起应用程序,在收集第2代时,会并行处理,具体原理是将Full GC过程切分成多个短暂子过程对线程进行冻结,在线程冻结时间之外,应用程序仍然可以正常运行。

  这主要通过将0代空间设置的很大,使Full GC时,CLR仍然能够在0代中进行内存分配,如果Full GC时0代内存也已用尽,那么应用程序将被挂起,等待Full GC的完成。在多CPU的情况下,可以使用和Server GC模式。这种GC模式有着很高的性能和效率。

  这种模式下,CLR为每个CPU创建一个专用的GC线程,每个CPU可以独立的为相应的heap执行GC操作,这些GC线程是以非并发的形式工作的,收集工作与线程正常工作不能同时进行,这就是说第0、1、2代的收集都会挂起应用线程。在.Net 4.0中,有一种新的垃圾收集机制,叫做后台收集。这种机制以concurrent GC为基础的,如上文所讲,Workstation GC with Concurrent模式中,在Full GC过程时,CLR仍然能够在0代中进行内存分配,如果Full GC时0代内存也已用尽,那么应用程序将被挂起,等待Full GC的完成。

  3.垃圾收集器是配合策略引擎工作的。策略引擎可以唤醒GC,它会根据GC启动的次数、频率、代龄情况等自发的启动GC,使GC工作。特别要注意的是,由程序人员手动的调用GC收集的代码,同样会影响策略引擎的工作,这样会给策略引擎错误的信号,从而导致GC的错误启动,所以在没有必要的情况下,一般不建议使用GC.Collect();手动回收。

  ● 综述比起垃圾收集器带来的微乎的性能损失,我们应该把精力放在程序的优化上,非托管资源的及时释放、字符串拼接、循环内的业务代码都是需要注意的地方。垃圾收集机制不是.Net也不是Java的专利,它已经有一段进化的历史,越来越多的案例也证明垃圾收集机制的优点,Exchange 2010的大部分模块就是基于托管环境的。

  二.关于实时编译机制JIT(Just In Time简称JIT)是.Net边运行边编译的一种机制,这种机制的命名来源于丰田汽车在20世纪60年代实行的一种生产方式,中文译为准时制。.Net 的JIT编译器在设计初衷和运行方式来上讲,都与丰田汽车的这种准时生产思想体系有着很大的相似之处,所以让我们先来透过准时生产方式来理解.Net的JIT机制吧。

  准时生产的基本思想可概括为在需要的时候,按需要的量生产所需的产品,这正是.Net JIT编译器的设计初衷,即在需要的时候编译需要的代码。

  相关文章:.Net Discovery系列之-深入理解平台机制与性能影响 (中) 

                       .Net Discovery系列-深入理解平台机制与性能影响(上)

时间: 2024-10-22 20:40:48

一起谈.NET技术,.Net Discovery系列-深入理解平台机制与性能影响(上)的相关文章

.Net D“.NET技术”iscovery系列-深入理解平台机制与性能影响(上)

转眼间<.Net Discovery>系列文章已经推出1年了,本文为该系列的第10-13篇文章,在本文中将对以前所讲的.Net平台知识做一个小小的总结与机制分析,引出并重点介绍这些机制对程序性能的影响与改进建议. 本文将分为四部分,分别讲述了:垃圾回收机制.即时编译机制.异常处理机制.字符串驻驻留机制的原理与性能改进建议. <.Net Discovery>系列的每篇文章撰写耗时都在2天以上,转载时麻烦著名作者Aicken(李鸣),并且未经作者同意,禁止一切商业用途! 一.关于垃圾回

一起谈.NET技术,.Net Discovery系列之-深入理解平台机制与性能影响 (中)

上一篇文章中Aicken为大家介绍了.Net平台的垃圾回收机制与其对性能的影响,这一篇中将继续为大家介绍.Net平台的另一批黑马-JIT.有关JIT的机制分析 ● 机制分析以C#为例,在C#代码运行前,一般会经过两次编译,第一阶段是C#代码向MSIL的编译,第二阶段是IL向本地代码的编译.第一阶段的编译成果是生成托管模块,第二阶段的编译成果是生成本地代码以供运行,从这里各位同学可以看出,第一阶段生成的MSIL是不能直接运行的.必须指出的是JIT在第一次编译IL后,会修改对应方法相应的内存地址入口

.“.NET研究”Net Discovery系列之-深入理解平台机制与性能影响 (中)

上一篇文章中Aicken为大家介绍了.Net平台的垃圾回收机制与其对性能的影响,这一篇中将继续为大家介绍.Net平台的另一批黑马-JIT.有关JIT的机制分析 ● 机制分析以C#为例,在C#代码运行前,一般会经过两次编译,第一阶段是C#代码向MSIL的编译,第二阶段是IL向本地代码的编译.第一阶段的编译成果是生成托管模块,第二阶段的编译成果是生成本地代码以供运行,从这里各位同学可以看出,第一阶段生成的MSIL是不能直接运行的.必须指出的是JIT在第一次编译IL后,会修改对应方法相应的内存地址入口

.Net Discovery系“.NET技术”列之-深入理解平台机制与性能影响 (中)

上一篇文章中Aicken为大家介绍了.Net平台的垃圾回收机制与其对性能的影响,这一篇中将继续为大家介绍.Net平台的另一批黑马-JIT.有关JIT的机制分析 ● 机制分析以C#为例,在C#代码运行前,一般会经过两次编译,第一阶段是C#代码向MSIL的编译,第二阶段是IL向本地代码的编译.第一阶段的编译成果是生成托管模块,第二阶段的编译成果是生成本地代码以供运行,从这里各位同学可以看出,第一阶段生成的MSIL是不能直接运行的.必须指出的是JIT在第一次编译IL后,会修改对应方法相应的内存地址入口

.Net Discovery系列之-深入理解平台机制与性能影“.NET研究”响(下)

三.关于异常捕获机制 虽然我们已经很辛苦了,但是仍然有很多原因使代码运行失败,如引用null引用.索引越界.内存溢出.类型转换失败等等.这就需要我们的代码有足够的容错能力,在代码运行失败时,及时.主动的处理这些异常. ● 机制分析 .Net 中基本的异常捕获与处理机制是由try-catch-finally块来完成的,它们分别完成了异常的监测.捕获与处理工作.一个try块可以对应零个或多个catch块,可以对应零个或一个finally块.不过没有catch的try似乎没有什么意义,如果try对应了

.Net Discovery系列之-深入理解平台机制与性“.NET技术”能影响(下)

三.关于异常捕获机制 虽然我们已经很辛苦了,但是仍然有很多原因使代码运行失败,如引用null引用.索引越界.内存溢出.类型转换失败等等.这就需要我们的代码有足够的容错能力,在代码运行失败时,及时.主动的处理这些异常. ● 机制分析 .Net 中基本的异常捕获与处理机制是由try-catch-finally块来完成的,它们分别完成了异常的监测.捕获与处理工作.一个try块可以对应零个或多个catch块,可以对应零个或一个finally块.不过没有catch的try似乎没有什么意义,如果try对应了

A10网络公司的AX系列应用交付平台建立行业性能记录

新的64位硬件和软件解决方案,增强SSL 2048位主要性能,虚拟机箱增强和Diameter协议支持A10 Networks应用交付解决方案技术领导公司于2011年5月12日发布了一个新的高级核心操作系统版本2.6.1版,支持其旗舰AX系列应用交付控制器新的硬件和软件型号和功能的增强,提供了该类别产品中最高的性能和全面的应用特性.A10网络的AX系列ADC是新一代的服务器 负载均衡器,创新的64位共享内存,多进程,多内核,多CPU架构使其在性能,可扩展性,效率和灵活性方面超越对手."2.6.1版

一起谈.NET技术,分清“语言/规范”以及“平台/实现”,以及跨平台.NET开发

在许多年前,"语言"就等同于"平台",例如C,C++以及最早的Ruby和Python等等.但是随着技术发展,出现了一些通用的平台,例如.NET和Java,逐渐这些平台上的语言也越来越多.再后来,某些语言在不同平台上的实现也越来越多,事情也变得有些复杂.技术在发展,但是从目前社区的讨论中,我发现许多朋友的观念还没有跟上.简单地说,如今的观念,一定要从"语言即平台"切换成"语言及平台",当分清"语言"和&quo

分布式缓存技术redis学习系列----深入理解Spring Redis的使用

关于spring redis框架的使用,网上的例子很多很多.但是在自己最近一段时间的使用中,发现这些教程都是入门教程,包括很多的使用方法,与spring redis丰富的api大相径庭,真是浪费了这么优秀的一个框架. Spring-data-redis为spring-data模块中对redis的支持部分,简称为"SDR",提供了基于jedis客户端API的高度封装以及与spring容器的整合,事实上jedis客户端已经足够简单和轻量级,而spring-data-redis反而具有&qu