首页
Python
Java
IOS
Andorid
NodeJS
JavaScript
HTML5
【
[翻译] 编写高性能 .NET 代码--第二章 GC -- 将长生命周期对象和大对象池化
】的更多相关文章
[翻译] 编写高性能 .NET 代码--第二章 GC -- 将长生命周期对象和大对象池化
将长生命周期对象和大对象池化 请记住最开始说的原则:对象要么立即回收要么一直存在.它们要么在0代被回收,要么在2代里一直存在.有些对象本质是静态的,生命周期从它们被创建开始,到程序停止才会结束.其它对象显然不需要永远存在下去,但他们的生命周期会存在程序的某些上下文里.它们的存活时间会超过0代(1代)回收.这些类型的对象可以作为池化对象的备选.这虽然需要你手动管理内存,但实际情况下这是一个很好的选择.另外一个重要的需要池化的对象是分配在LOH里的大对象. 没有一个单一的标准方案或者API来实现对象…
[翻译] 编写高性能 .NET 代码--第二章 GC -- 避免使用终结器,避免大对象,避免复制缓冲区
避免使用终结器 如果没有必要,是不需要实现一个终结器(Finalizer).终结器的代码主要是让GC回收非托管资源用.它会在GC完成标记对象为可回收后,放入一个终结器队列里,在由另外一个线程执行队列里对象的终结器方法.这就意味着,如果你实现一个类的终结器,你必须保证在它在终结器执行后能被正常回收.这需要消耗一些CPU资源在清理对象上,会极大降低GC的整体效率. 如果你实现一个终结器,你也必须实现一个IDisposable接口用来清理资源,并在Dispose方法里调用GC.SupperessFin…
[翻译] 编写高性能 .NET 代码--第二章 GC -- 减少分配率, 最重要的规则,缩短对象的生命周期,减少对象层次的深度,减少对象之间的引用,避免钉住对象(Pinning)
减少分配率 这个几乎不用解释,减少了内存的使用量,自然就减少GC回收时的压力,同时降低了内存碎片与CPU的使用量.你可以用一些方法来达到这一目的,但它可能会与其它设计相冲突. 你需要在设计对象时仔细检查每个它并问自己: 我真的需要这个对象吗? 这个字段是我需要的吗? 我能减少数组的尺寸吗? 我能缩小primitives的尺寸吗(用Int32替换Int64,其它)? 这些对象,是否只有在极少数情况下,或者只有初始化的时候才用到? 是否能将一些类转为结构体使他们在栈上分配或者成为某个对象的一部分?…
[翻译] 编写高性能 .NET 代码--第二章 GC -- 减少大对象堆的碎片,在某些情况下强制执行完整GC,按需压缩大对象堆,在GC前收到消息通知,使用弱引用缓存对象
减少大对象堆的碎片 如果不能完全避免大对象堆的分配,则要尽量避免碎片化. 对于LOH不小心就会有无限增长,但LOH使用的空闲列表机制可以减轻增长的影响.利用这个空闲列表,我们可以在两块分配区域中间找到你所想要的可分配区域. 要做到这一点,就需要保证你在LOH里的分配都按照同一个尺寸或者同一个尺寸的倍数进行.例如,一个常见的需求是在LOH里分配缓冲区.要确保分配的每个缓冲区都是一个大小,或者是一个知名数字(1M)的倍数,而不要创建大小不一的缓冲区.这样做的话,如果一个缓冲区被回收,那么下一个缓冲区…
[翻译] 编写高性能 .NET 代码--第二章 GC -- 配置选项
配置选项 在基于"less rope to hang yourself with"思想下,.NET 框架没有给开发提供很多太多的配置选项.但在大多数情况下,GC会跟你的硬件配置,及可用资源以及程序自己的行为做调整.当然也提供一些高级的配置使用,但这取决于你程序的类型. 工作站与服务器 你首要的是为应用选择是在工作站还是服务器模式下运行. 系统默认为工作站模式.在这种模式下,GC在触发回收时,回收线程与当前主线程的优先级一样.对于简单的应用程序,特别是存在工作站里有多个托管进程需要做交互…
[翻译]编写高性能 .NET 代码 第二章:垃圾回收
返回目录 第二章:垃圾回收 垃圾回收是你开发工作中要了解的最重要的事情.它是造成性能问题里最显著的原因,但只要你保持持续的关注(代码审查,监控数据)就可以很快修复这些问题.我这里说的"显著的原因",实际上是我们对垃圾回收的理解和期望不正确导致的.在.NET开发中,内存的性能问题和CPU的性能问题一样多,这就是单独开一章主要描述这个问题的原因. 当我们提及垃圾回收造成的开销时,就会不如自主的紧张起来,但一旦你理解它,就能很好的优化你的程序.在后面文章里,你可以看到GC可以在大多数情况下,…
[翻译]编写高性能 .NET 代码 第二章:垃圾回收 基本操作
返回目录 基本操作 垃圾回收的算法细节还在不断完善中,性能还会有进一步的提升.下文介绍的内容在不同的.NET版本里会略有不同,但大方向是不会有变动的. 在.net进程里会管理2个类型的内存堆:托管和非托管.本地代码申请的,以及由CLR申请的都是非托管内存,使用Windows API 的 VirtualAlloc 方法进行申请.CLR里分配的托管对象则分配在托管堆里,这些对象可以被垃圾回收处理. 在托管堆里有还进一步分为小对象对和大对象堆(LOH).每个对象类型都有自己的一段堆内存段.每段的大小根…
[翻译]编写高性能 .NET 代码 第一章:性能测试与工具 -- 平均值 vs 百分比
<<返回目录 平均值 vs 百分比 在考虑要性能测试的目标值时,我们需要考虑用什么统计口径.大多数人都会首选平均值,但在大多数情况下,这个正确的,但你也应该适当的考虑百分数.但你有可用性的要求,作为性能测试的目标里肯定会有用百分比作的要求.举个栗子:"数据库请求的平均延迟必须小于10ms,95%是请求必须小于100ms" ...(这里我省略了对"95%是请求必须小于100ms"的翻译说明,我觉得中国的程序猿应该看得懂我翻译的那句话) 1,2,2,4,5,…
[翻译]编写高性能 .NET 代码 第一章:工具介绍 -- Visual Studio
<<返回目录 Visual Studio vs虽然不是全宇宙唯一的IDE,但它是.net开发人员最常用的开发工具.它自带一个性能分析工具,你可以使用它来做开发,不同的vs版本在工具上会略有差别. VS可以分析CPU使用率,内存分配以及资源锁情况.它能在你开发与运行中对项目做综合的测试. 它很强大,可以准确的测量运行了生产环境数据的大型应用程序.但是它集成在vs里面,如果你希望在生产环境下使用,需要有一个独立的性能监控工具.这个微软帮你想好了,从vs2013以后的版本里,在安装光盘里有一个独立版…
[翻译]编写高性能 .NET 代码 第一章:工具介绍 -- Performance Counters(性能计数器)
<<返回目录 Performance Counters(性能计数器) 性能计数器是监视应用程序和系统性能的最简单的方法之一.它有几十个类别数百个计数器在,包括一些.net特有的计数器.要访问这些可以通过系统自带的 性能监控程序(perfmon.exe)来实现. 图1-2.是PerfMon的主要窗口,它显示一个小的时间段内处理器计数器.垂直线表示当前实例,默认情况下100秒钟后图形将换行. 图1-3.这是很多类别里的其中一个计数器,还显示了适用这个计数器的应用实例. 每个计数器都有一个类别和一个…