using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Web.SessionState;namespace WZW.Web.Biz.Core
{
    public class DictManager
    {
        private static DictManager instance = new DictManager();        private static readonly object synRoot = new object();        // 字典目录Map
        private HashMap dictCatalogMap = new HashMap();        // 字典Map
        private HashMap dictMap = new HashMap();        // 字典列表Map
        private HashMap dictListMap = new HashMap();        public static DictManager GetInstance()
        {
            return instance;
        }        private void InitDict()
        {
            lock (synRoot)
            {
                dictCatalogMap = new HashMap();
                dictMap = new HashMap();
                dictListMap = new HashMap();                // 获取字典索引
                SqlParaMap spm = new SqlParaMap();
                spm.AddOrderyBy("dict_memoni");
                List<SysDict> sysDictList = SysDictManager.GetInstance().QuerySysDictForList(spm);
                foreach (SysDict sysDict in sysDictList)
                {
                    // 初始化字典列表
                    DictCatalog dictCatalog = new DictCatalog();
                    dictCatalog.Memoni = sysDict.Dict_memoni;
                    dictCatalog.Name = sysDict.Dict_name;
                    dictCatalog.Description = sysDict.Note;
                    dictCatalogMap.Add(sysDict.Dict_memoni, dictCatalog);                    // 初始化数据字典列表
                    spm = new SqlParaMap();
                    spm.AddEquals("dict_memoni", sysDict.Dict_memoni);
                    spm.AddOrderyBy("sort,dict_code");
                    List<SysDictItem> sysDictItemList = SysDictManager.GetInstance().QuerySysDictItemForList(spm);
                    List<Dict> dictList = new List<Dict>();
                    foreach (SysDictItem sysDictItem in sysDictItemList)
                    {
                        Dict dict = this.GetDict(sysDictItem);                        dictMap.Add(this.GetKey(dict.Memoni, dict.Code), dict);
                        dictList.Add(dict);
                    }                    dictListMap.Add(sysDict.Dict_memoni, dictList);
                }
            }
        }       public string GetText(string memoni, string code)
        {
            if (dictCatalogMap.Count == 0)
            {
                this.InitDict();
            }            string key = this.GetKey(memoni, code);            if (dictMap[key] != null)
            {
                return ((Dict)dictMap[key]).Text;
            }
            else
            {
                return code;
            }
        }     
        public List<Dict> getDictList(string memoni)
        {
            if (dictCatalogMap.Count == 0)
            {
                this.InitDict();
            }            if (dictListMap.ContainsKey(memoni))
            {
                return (List<Dict>)dictListMap[memoni];
            }            return new List<Dict>();
        }        private string GetKey(string memoni, string code)
        {
            return memoni + "@@" + code;
        }        private Dict GetDict(SysDictItem sysDictItem)
        {
            Dict dict = new Dict();
            if (sysDictItem != null)
            {
                dict.Memoni = sysDictItem.Dict_memoni;
                dict.Code = sysDictItem.Dict_code;
                dict.Text = sysDictItem.Dict_text;
                dict.Color = sysDictItem.Color;
                dict.Sort = sysDictItem.Sort;
                dict.Description = sysDictItem.Note;
            }
            return dict;
        }
    }
}以上代码是初始化字典表一个单例中去,然后在调用绑定到下拉框控件中去的时候,使用DictManager.GetInstance().getDictList(this.memoni);人少的时候发送IIS站点运行正常,人多的时候应用程序池就挂了,说堆栈溢出, 么样解决

解决方案 »

  1.   

    InitDict()   每次都会被 调用
    导致:
                    dictCatalogMap = new HashMap();
                    dictMap = new HashMap();
                    dictListMap = new HashMap();
    每次都会被 新建新的字典;(旧字典留在内存中,交给了 内存回收器)导致:
                    新的3个字典都会被再次赋值;(内存中就会添加新数据)——————————————————————————————
    内存回收器不会频繁工作;
    但是你每次都会新建新 字典,添加新数据,旧数据 直接就给 去掉引用了;内存 不爆掉才怪呢!!!
      

  2.   

    我看了一下代码——代码在本质上没有明显的内存泄漏情况;我也不知道楼主说的 人多的时候是什么时候;
    也不知道  每初始化一次,需要浪费多少内存——初始化多少次就会内存溢出.....
    现在能够教楼主做的就是这个了: lock (synRoot)
     {
         if (dictCatalogMap.Count == 0)  //在多线程并发时,可能1线程完成初始化,2线程也近来要完成初始化,这时唯一一个多线程可能需要控制的地方;
         {
             //你的代码
         }
     }
      

  3.   

    就是 防止 多线程的  双判断if(条件)
    {
        lock(锁)
        {
             if(条件)
             {
                 自己的代码
             }
        }
    }
      

  4.   

    有几处没看明白
            private static DictManager instance = new DictManager();
    这是在干什么?类里建一个自己类的静态成员???
            private void InitDict()
            {
                lock (synRoot)
                {
                    dictCatalogMap = new HashMap();
                    dictMap = new HashMap();
                    dictListMap = new HashMap();这里为什么不用clear?
    看不懂
      

  5.   

    private void InitDict()
            {
                lock (synRoot)
                {             这里少了一个判断语句.  当 N个线程同时调用 InitDict 后,  谁先获得锁谁就先执行完LOCK,然后释放锁,交给下一个线程. 下一个线程继续执行 InitDict ,获得锁,又执行初始化....所以你这里你锁定后应该多一个判断,判断是否已经初始化了.写完代码,你可以弄个多线程访问数据测试一下.
      

  6.   

    Fields: date time c-ip c-port s-ip s-port cs-version cs-method cs-uri sc-status s-siteid s-reason s-queuename
    2012-02-21 06:16:50 219.140.160.222 9089 218.197.81.61 80 - - - - - Timer_ConnectionIdle -
    2012-02-21 06:16:50 221.234.44.19 33730 218.197.81.61 80 - - - - - Timer_ConnectionIdle -
    2012-02-21 06:17:01 111.180.146.26 3628 218.197.81.61 80 - - - - - Timer_ConnectionIdle -
    2012-02-21 06:17:01 125.221.102.151 50073 218.197.81.60 80 - - - - - Timer_ConnectionIdle -
    2012-02-21 06:17:01 59.69.25.161 54779 218.197.81.60 80 - - - - - Timer_ConnectionIdle -
    2012-02-21 06:17:01 111.180.146.26 3619 218.197.81.61 80 - - - - - Timer_ConnectionIdle -
    2012-02-21 06:17:06 113.57.213.8 59226 218.197.81.61 80 - - - - - Timer_ConnectionIdle -
    2012-02-21 06:17:08 219.139.58.7 4383 218.197.81.61 80 HTTP/1.1 GET /zsjy/hbuezzzs/zzzs/Image.aspx - 1984049823 Connection_Abandoned_By_AppPool hbuezzzs
    2012-02-21 06:17:08 219.139.58.7 4385 218.197.81.61 80 HTTP/1.1 POST /zsjy/hbuezzzs/zzzs/Login.aspx - 1984049823 Connection_Abandoned_By_AppPool hbuezzzs
    2012-02-21 06:17:11 219.140.160.222 9053 218.197.81.61 80 - - - - - Timer_ConnectionIdle -
    2012-02-21 06:17:11 219.140.160.222 9062 218.197.81.61 80 - - - - - Timer_ConnectionIdle -
    2012-02-21 06:17:15 116.209.92.246 5963 218.197.81.61 80 - - - - - Timer_ConnectionIdle -
    2012-02-21 06:17:20 113.57.213.8 58416 218.197.81.61 80 - - - - - Timer_ConnectionIdle -
    2012-02-21 06:17:30 116.209.92.246 5962 218.197.81.61 80 - - - - - Timer_ConnectionIdle -
    2012-02-21 06:17:41 116.209.92.246 5959 218.197.81.61 80 - - - - - Timer_ConnectionIdle -
    2012-02-21 06:17:45 116.209.92.246 5977 218.197.81.61 80 - - - - - Timer_ConnectionIdle -
    2012-02-21 06:17:45 119.99.66.81 48220 218.197.81.61 80 - - - - - Timer_ConnectionIdle -
    2012-02-21 06:17:45 59.173.217.86 39296 218.197.81.61 80 - - - - - Timer_ConnectionIdle -
    2012-02-21 06:17:45 116.209.92.246 5961 218.197.81.61 80 - - - - - Timer_ConnectionIdle -
    2012-02-21 06:17:45 116.209.92.246 5964 218.197.81.61 80 - - - - - Timer_ConnectionIdle -
    2012-02-21 06:17:45 116.209.92.246 5966 218.197.81.61 80 - - - - - Timer_ConnectionIdle -
    2012-02-21 06:17:45 116.209.92.246 5960 218.197.81.61 80 - - - - - Timer_ConnectionIdle -
    2012-02-21 06:17:45 119.99.66.81 48218 218.197.81.61 80 - - - - - Timer_ConnectionIdle -
    2012-02-21 06:17:50 202.103.26.3 19543 218.197.81.61 80 - - - - - Timer_ConnectionIdle -
    2012-02-21 06:17:55 116.209.92.246 5956 218.197.81.61 80 - - - - - Timer_ConnectionIdle -
    2012-02-21 06:18:15 221.234.44.25 29904 218.197.81.61 80 - - - - - Timer_ConnectionIdle -
    2012-02-21 06:18:20 61.135.249.207 29661 218.197.81.61 80 - - - - - Timer_ConnectionIdle -
    2012-02-21 06:18:46 222.167.84.195 51573 218.197.81.61 80 - - - - - Timer_ConnectionIdle -
    2012-02-21 06:18:46 222.167.84.195 51574 218.197.81.61 80 - - - - - Timer_ConnectionIdle -
    2012-02-21 06:19:30 221.233.198.51 14298 218.197.81.61 80 - - - - - Timer_ConnectionIdle -
    2012-02-21 06:20:01 58.55.51.86 49804 218.197.81.61 80 HTTP/1.1 GET /zsjy/zs/images/image.swf - 1984049823 Timer_MinBytesPerSecond DefaultAppPool
    2012-02-21 06:20:15 121.63.167.228 1896 218.197.81.61 80 - - - - - Timer_ConnectionIdle -
    2012-02-21 06:20:15 121.63.167.228 1902 218.197.81.61 80 - - - - - Timer_ConnectionIdle -
    2012-02-21 06:20:15 121.63.167.228 1897 218.197.81.61 80 - - - - - Timer_ConnectionIdle -
    2012-02-21 06:20:15 121.63.167.228 1901 218.197.81.61 80 - - - - - Timer_ConnectionIdle -
    2012-02-21 06:20:15 121.63.167.228 1906 218.197.81.61 80 - - - - - Timer_ConnectionIdle -
    2012-02-21 06:20:15 121.63.167.228 1898 218.197.81.61 80 - - - - - Timer_ConnectionIdle -
    2012-02-21 06:20:20 58.19.176.210 1916 218.197.81.61 80 - - - - - Timer_ConnectionIdle -
    2012-02-21 06:20:25 221.233.198.51 13796 218.197.81.61 80 - - - - - Timer_MinBytesPerSecond -
    IIS频繁重启
      

  7.   

        public class DictManager
        {
            private static DictManager instance = new DictManager();还是感觉你的这个成员,造成了逻辑上的死循环,你自己看看吧。
      

  8.   

    再说了你lock 的地方也不对啊返回实例的方法也没判断啊
            public static DictManager GetInstance()
            {
                return instance;
            }        public static DictManager GetInstance()
            {
                if (instance == null)
                {                lock (synRoot)
                    {                    if (instance == null)
                        {
                            instance = new Singleton();
                        }
                    }
                }
                return instance;
            }而且还得私有化构造函数private DictManager(){}要这样啊!
      

  9.   

    上面的代码已经按你们的改掉了,IIS还是有报
    为应用程序池 'XXX' 提供服务的进程在与 World Wide Web Publishing 服务通信时遇到致命错误。进程 ID 为 '2088'。数据字段包含错误号。
      

  10.   

    1. 单键模式没有使用私有构造函数,并且也要使其是线程安全的类
    2. 每次都要初始化
    dictCatalogMap = new HashMap();
    dictMap = new HashMap();
    dictListMap = new HashMap();
    这3个对象。这样lock了也没什么意义了吧可能理解的不对
      

  11.   

    已经改成如下代码了,且可以确保类不是通过NEW之后再调的方法,都是通过GetInstance走的,还是出现为应用程序池 'XXX' 提供服务的进程在与 World Wide Web Publishing 服务通信时遇到致命错误。进程 ID 为 '2088'。数据字段包含错误号。然后IIS就过一分挂掉,
     // 字典Map
            private HashMap dictMap = new HashMap();        // 字典列表Map
            private HashMap dictListMap = new HashMap();        public static DictManager GetInstance()
            {
                if (instance == null)
                {
                    lock (synRoot)
                    {
                        if (instance == null)
                        {
                            instance = new DictManager();
                        }
                    }
                }            return instance;
            }        private void InitDict()
            {
                lock (synRoot)
                {
                    dictCatalogMap.Clear();
                    dictMap.Clear();
                    dictListMap.Clear();
      

  12.   

    1、private static DictManager instance = new DictManager();---楼主的意图可能是想建立Singleton模式的DictManager实例吧。但是
    (1)私有静态实例初始为instance=null;
    (1)少了private或者protected的构造函数 
    (2)GetInstance也有错误
    private static DictManager instance = null;
    private DictManager(){}
    public static DictManager GetInstance()
    {
    if(instance==null)
      instance = new DictManager();
    return instance;
    }
    2、lock/unlock应成对出现,而InitDict函数中只加锁,却没解锁
    3、dictCatalogMap = new HashMap();
                    dictMap = new HashMap();
                    dictListMap = new HashMap();
    不要重复初始化
      

  13.   

    又看了看,改完后的,建议把getDictList这个方法获取改成加锁的吧。你返回了一个单例的成员中的引用类型数据给一堆人用,一定要加锁。
      

  14.   

    把getDictList这个方法获取改成加锁