Dictionary CPU 100%

  昨天服務器的CPU忽然100%,此服務已經運行幾年了,都平安無事。既然問題出現固然要找出這個遺留多年的小几率問題。出現cpu 100% 通常就是哪裏出現了沒法跳出的死循環。
安全

  一、獲取進程的內存信息

  服務器使用的window server 直接右鍵建立轉儲文件便可。這個直接點點的方式是使用window server最方便的地方(^_^)。服務器

  二、加載內存文件信息

  將文件複製本地,直接拖拽到windbg中。(windbg直接在window 應用商店下載便可)多線程

  

 

  三、獲取進程內耗時線程

  在0:000 輸入框中輸入!runaway 敲回車,獲取線程佔用cpu時間spa

  

 

   

   四、獲取線程的棧信息

  從cpu的線程佔用時間來看,線程64,89,96,95,90佔用的時間最長,能夠初步判定問題就出如今這幾個線程中。輸入:~64s進入該線程(64表明的是線程id)線程

  

  進入該線程後就能夠加載線程的棧信息了,在命令框中輸入!CLRStack 。若是出現圖示信息說明須要單獨加載SOS.dll 文件。使用everything軟件全局搜索該dll文件位置,而後在輸入框中:.load 全路徑\SOS.dll。加載完成再次輸入:!CLRStack 就能夠正常顯示棧信息了。3d

  

  五、問題定位

  從棧信息來看,線程一直停留在:System.Collections.Generic.Dictionary`2[[System.__Canon, mscorlib],[System.__Canon, mscorlib]].FindEntry(System.__Canon)這個方法裏面,調用這個方法的類是:Aop.Api.Parser.AopJsonParser,這個類是支付寶官方sdk中的。先看FindEntry這個方法幹了啥。直接官網查看源碼:code

  

private int FindEntry(TKey key) {
            if( key == null) {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
            }
 
            if (buckets != null) {
                int hashCode = comparer.GetHashCode(key) & 0x7FFFFFFF;
                for (int i = buckets[hashCode % buckets.Length]; i >= 0; i = entries[i].next) {
                    if (entries[i].hashCode == hashCode && comparer.Equals(entries[i].key, key)) return i;
                }
            }
            return -1;
        }

  從源碼來就是判斷key是否存在,看來就是死循環for裏面了。再來看這個dictionary是用來幹啥了的,反編譯Aop dll文件server

 

private static Dictionary<string, AopAttribute> GetAopAttributes(Type type)
{
    Dictionary<string, AopAttribute> dictionary = null;
    if (!AopJsonParser<T>.attrs.TryGetValue(type.FullName, out dictionary) || (dictionary == null))
    {
        dictionary = new Dictionary<string, AopAttribute>();
private static readonly Dictionary<string, Dictionary<string, AopAttribute>> attrs;
 

 

  從源碼能夠看見定義了一個靜態Dictionary attrs變量,既然是靜態變量,會出現多線程競爭問題。官網也明確說明Dictionary 是非線程安全的,若是多線程讀寫須要本身去寫程序保證線程安全或者使用ConcurrentDictionary。blog

  六、問題

  問題的根本緣由是多線程多寫非線程安全Dictionary,致使在FindEntry方法死循環。進程

相關文章
相關標籤/搜索