构建高性能ASP.NET站点 第七章 如何解决内存的问题(前篇)—托管资源优化—垃圾回收机制深度剖析

简介:
构建高性能ASP.NET 站点  第七章  如何解决内存的问题( 前篇)— 托管资源优化垃圾回收机制剖析
    前言:本章主要详细的讲述如何因内存问题而导致的性能问题,很多的时候都是深入.NET 内核进行分析,然后给出解决方案,同时,本系列的其他文章,也争取做到:深入浅出。
 
   本篇是为后面的做个铺垫,而且比较的精彩。只有真正的理解了本篇,后面才可以顺利的走下去。
 
本篇的议题如下:
内存问题概述( 前篇)
托管资源优化(前篇)
          对象的生命周期(前篇)
          对象的 代“(前篇)
          大对象堆(LOH)  (前篇)
         CLR 计数器的使用          (前篇)
         CLR Profiler 的使用(中篇)
          垃圾回收器的不同版本(中篇)
          对象使用注意事项(中篇)
          常用优化措施(后篇)
非托管资源优化
Session 会话的优化
 
   内存问题概述
    和CPU 一样,内存也是一个直接影响服务端性能的重要的硬件资源。
   一般来说,如果服务端内存不足,从导致以下两个问题产生:
1.        导致服务端把一些原本要写到内存中的数据,写到硬盘上面。这样不仅仅加大了CPU 和磁盘的I/O 操作,同时也延长了读取这些数据的时间。
2.        阻止了一些缓存策略的使用。
 
   对于内存不足,一直最快最直接的方式就是去买内存条加在服务器上面。但是这样存在一个隐患的问题就是:如果加了新的内存之后,服务端又面临内存不足的问题,我们不可能无止境的加内存条,那么我们就必须从站点本身来解决这个问题,例如从服务端的配置,对站点的代码进行分析,优化。
 
   托管资源优化
对于托管资源,相信大家并不陌生了,简单的说就是:在C# 的托管堆上面创建的资源,或者说通过new 产生的对象。
在深入讲解之前,我们首先来看看对象的生命周期
 
   对象的生命周期
当我们用new 关键字创建了一个对象的时候,这个对象就被分配到CRL 托管堆上面。这个托管堆是在内存中的。而且这个分配对象空间的速度是非常的快的,因为每次都是在托管堆的最后面划出一定的空间来给这个对象,不用去堆上面需找合适大小的空间。
        如果当托管堆准备为一个对象分配空间的时候,发现托管堆上面的空间太小了,不足以分配给这个新的对象,那么CLR 就开始运行垃圾回收机制了。我们知道:垃圾回收机制会把那些在托管堆上面没有了引用指向的那些对象都清理掉,同时也会把托管堆上面现存的对象进行压缩。
        但是有一点需要清楚:如果此时进行了垃圾回收的时候,清除了一些没有用的对象,但是只有在下一次来回收进行的时候,上次垃圾回收清除的对象才真正的从内存中消除( 此时,还有一些“对象复苏“等话题就不在赘述)
 
   下面就来讲述一些垃圾回收的话题。
 
   对象的 代“
CLR 进行垃圾回收的时候,垃圾回收器回去托管堆上面去检查对象是否可以被回收,这个检查过程是非常消耗资源的。为了避免每次垃圾回收都要便利托管堆上面的所有对象,CLR 给把托管堆上面的对象用来划分,例如,第一代,第二代。然后每次便利扫描托管堆的时候,就去扫描某一个中的对象,这样性能就好点。 
在托管堆上面,可以把对象分为三个”:0 代,1 代,2 代,仅此这三个代。每个对象都是从0 代开始的。一个对象每经历一次垃圾回收,并且这个对象还在使用中,那么这个对象的“代“就会增加1 代。例如,如果在0 代的对象,经历了一次垃圾回收之后,他的代就是1 代,如果是1 代的对象,最后就会变为2 代。如果对象本身已经是2 代了,不管经历多少次垃圾回收( 如果对象一直在使用) ,那么这个对象还是2 代。
 
CLR 垃圾回收中有句话要记得:”  ’ 数越大,被回收的可能性就越小。而且一些性能优化就是根据这个进行的。
 
每次CLR 在进行垃圾回收的时候,都会优先的去扫描第0 代的对象,所以,一些新的,临时使用的对象可以被立刻的清除。相比而言,垃圾回收器扫描第1 代对象的频率就没有第0 代强,扫描第2 代对象的频率就更低了。所以说:对象存活的时间越长,就越难被回收,而且一直占据CLR 的内存资源。
 
还有有点需要注意的就是 :如果CLR 决定要扫描了第1 代了,同时也用扫描第0 代的对象,同时如果,CLR 扫描第2 代对象,那么第0 代,第1 代对象都会被扫描。
 
所以,从这里可以得出:我们尽量避免把原本需要立刻回收的的对象变为长期存活的对象。通俗点说就是:如果一个对象本来已经存活在0 代的,然后用完就回收的,我们不要让这个对象一直存活到第1 代,甚至第2 代。在编程上面基本就是这样的实现思路:尽可能晚的实例化对象,尽可能早的释放对象。
 
     大对象堆 (Large Objecet Heap)
我们之前讲述了的一些话题,CLR 除了上面的一般的堆( 一般的new 对象分配空间的那个堆) CLR 中还存在另外的一个堆:专门用来放置那些大于了58k 的对象的堆,大对象堆
如果new 一个对象的时候,这个对象的大小超过了85k ,那么CLR 就会把这个对象放在LOH 上面。如果此时LOH 的空间不足了,那么CLR 就会启动垃圾回收器去扫描LOH 堆和那个一般堆上面的第2 代对象,我们之前说过,如果扫描第2 代对象,就同时扫描第1 代,第0 代,那么实际相当于扫描了整个托管堆,性能影响可想而知。
而且不想之前那个一般堆,在LOH 上面的对象被垃圾回收器回收之后,上面的大对象是不会被压缩的,那么LOH 这个堆上面就可能存在一些空间碎片,然后分配新的大对象的时候,就要找空间,甚至进行碎片的整理,大家可以联想一下我们电脑的磁盘碎片整理。
 
OK ,今天就讲到这里,理论有点多,但是都是基本要清楚和掌握的,希望多多理解。
 
















本文转自yanyangtian51CTO博客,原文链接:  http://blog.51cto.com/yanyangtian/495267 ,如需转载请自行联系原作者











相关文章
|
1月前
|
编解码 算法 Java
构建高效的Android应用:内存优化策略详解
随着智能手机在日常生活和工作中的普及,用户对移动应用的性能要求越来越高。特别是对于Android开发者来说,理解并实践内存优化是提升应用程序性能的关键步骤。本文将深入探讨针对Android平台的内存管理机制,并提供一系列实用的内存优化技巧,以帮助开发者减少内存消耗,避免常见的内存泄漏问题,并确保应用的流畅运行。
|
1月前
|
传感器 API Android开发
构建高效的安卓应用:从内存优化到电池续航
【2月更文挑战第27天】 随着智能手机成为我们日常生活中不可或缺的一部分,用户对应用程序的性能和效率要求越来越高。对于安卓开发者来说,优化应用的内存使用和延长电池寿命已经成为提升用户体验的关键任务。本文将深入探讨在安卓开发中如何通过有效的内存管理和电池使用策略来构建一个高效且持久的应用。我们将分析常见的内存泄漏问题,讨论如何利用安卓的电池管理API以及探索最新的安卓系统特性,帮助开发者们提升应用性能,并确保它们能在资源受限的设备上顺畅运行。
|
9天前
|
移动开发 Android开发 开发者
构建高效Android应用:采用Kotlin进行内存优化的策略
【4月更文挑战第18天】 在移动开发领域,性能优化一直是开发者关注的焦点。特别是对于Android应用而言,由于设备和版本的多样性,确保应用流畅运行且占用资源少是一大挑战。本文将探讨使用Kotlin语言开发Android应用时,如何通过内存优化来提升应用性能。我们将从减少不必要的对象创建、合理使用数据结构、避免内存泄漏等方面入手,提供实用的代码示例和最佳实践,帮助开发者构建更加高效的Android应用。
15 0
|
11天前
|
缓存 移动开发 Java
构建高效的Android应用:内存优化策略
【4月更文挑战第16天】 在移动开发领域,尤其是针对资源有限的Android设备,内存优化是提升应用性能和用户体验的关键因素。本文将深入探讨Android应用的内存管理机制,分析常见的内存泄漏问题,并提出一系列实用的内存优化技巧。通过这些策略的实施,开发者可以显著减少应用的内存占用,避免不必要的后台服务,以及提高垃圾回收效率,从而延长设备的电池寿命并确保应用的流畅运行。
|
23天前
|
存储 缓存 NoSQL
Redis 服务器指南:高性能内存数据库的完整使用指南
Redis 服务器指南:高性能内存数据库的完整使用指南
|
1月前
|
缓存 移动开发 Java
构建高效Android应用:内存优化实战指南
在移动开发领域,性能优化是提升用户体验的关键因素之一。特别是对于Android应用而言,由于设备和版本的多样性,内存管理成为开发者面临的一大挑战。本文将深入探讨Android内存优化的策略和技术,包括内存泄漏的诊断与解决、合理的数据结构选择、以及有效的资源释放机制。通过实际案例分析,我们旨在为开发者提供一套实用的内存优化工具和方法,以构建更加流畅和高效的Android应用。
|
1月前
|
监控 Java Android开发
构建高效Android应用:从内存管理到性能优化
【2月更文挑战第30天】 在移动开发领域,打造一个流畅且响应迅速的Android应用是每个开发者追求的目标。本文将深入探讨如何通过有效的内存管理和细致的性能调优来提升应用效率。我们将从分析内存泄露的根本原因出发,讨论垃圾回收机制,并探索多种内存优化策略。接着,文中将介绍多线程编程的最佳实践和UI渲染的关键技巧。最后,我们将通过一系列实用的性能测试工具和方法,帮助开发者监控、定位并解决性能瓶颈。这些技术的综合运用,将指导读者构建出更快速、更稳定、用户体验更佳的Android应用。
|
1月前
|
缓存 监控 API
构建高效的Android应用:从内存优化到电池寿命
【2月更文挑战第27天】 在移动开发领域,构建一个既高效又省电的Android应用是每个开发者的梦想。本文深入探讨了Android应用性能优化的关键策略,包括内存管理和电池使用效率。我们将分析常见的内存泄漏问题,并提供解决方案,同时介绍最新的Android电池优化技术。通过实例和最佳实践,读者将学会如何打造一个更加流畅、响应迅速且电池友好的Android应用。
|
1月前
|
传感器 缓存 Android开发
构建高效的Android应用:从内存优化到电池寿命
【2月更文挑战第23天】在移动开发领域,性能优化是一个持续的挑战。特别是对于Android应用来说,由于设备多样性和碎片化问题,开发者需要采取一系列策略来保证应用的流畅运行。本文深入探讨了Android应用的性能优化,包括内存管理、电池使用效率和UI渲染。我们将提供实用的技巧和最佳实践,帮助开发者构建更加高效、响应迅速的应用,从而改善用户体验并延长设备电池寿命。
14 1
|
1月前
|
监控 Java Android开发
构建高效Android应用:从内存优化到电池寿命
【2月更文挑战第18天】在移动设备的生态系统中,资源管理是确保用户满意度的关键。特别是对于Android开发者来说,优化应用的内存使用和延长电池寿命是提升用户体验的重要方面。本文将深入探讨Android平台上的内存管理机制,提供实用的代码级优化技巧,并讨论如何通过调整应用行为来减少能量消耗,最终目标是为开发者提供一套全面的技术策略,以打造更加高效、响应迅速且电池友好的Android应用。
32 5