前言:本章主要詳細的講述如何因內存問題而致使的性能問題,不少的時候都是深刻.NET內核進行分析,而後給出解決方案,同時,本系列的其餘文章,也爭取作到:深刻淺出。html
本篇是爲後面的作個鋪墊,並且比較的精彩。只有真正的理解了本篇,後面才能夠順利的走下去。編程
本篇的議題以下:緩存
內存問題概述(前篇)性能優化
託管資源優化(前篇)服務器
對象的生命週期(前篇)ide
對象的」代「(前篇)性能
大對象堆(LOH) (前篇)優化
CLR計數器的使用(前篇)htm
非託管資源優化對象
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中還存在另外的一個堆:專門用來放置那些大於了85k的對象的堆,大對象堆。
若是new一個對象的時候,這個對象的大小超過了85k,那麼CLR就會把這個對象放在LOH上面。若是此時LOH的空間不足了,那麼CLR就會啓動垃圾回收器去掃描LOH堆和那個通常堆上面的第2代對象,咱們以前說過,若是掃描第2代對象,就同時掃描第1代,第0代,那麼實際至關於掃描了整個託管堆,性能影響可想而知。
並且不想以前那個通常堆,在LOH上面的對象被垃圾回收器回收以後,上面的大對象是不會被壓縮的,那麼LOH這個堆上面就可能存在一些」空間碎片」,而後分配新的大對象的時候,就要找空間,甚至進行碎片的整理,你們能夠聯想一下咱們電腦的磁盤碎片整理。
原文連接:http://www.cnblogs.com/yanyangtian/archive/2011/02/17/1956768.html