首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > C# >

急求上面的代码引起的堆栈溢出的原因,么样解决

2012-12-17 
急求下面的代码引起的堆栈溢出的原因,么样解决using Systemusing System.Collections.Genericusing Syst

急求下面的代码引起的堆栈溢出的原因,么样解决


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、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();
不要重复初始化
[其他解释]
就是 防止 多线程的  双判断

if(条件)
{
    lock(锁)
    {
         if(条件)
         {
             自己的代码
         }
    }
}
[其他解释]
    public class DictManager
    {
        private static DictManager instance = new DictManager();

还是感觉你的这个成员,造成了逻辑上的死循环,你自己看看吧。
[其他解释]
有几处没看明白
        private static DictManager instance = new DictManager();
这是在干什么?类里建一个自己类的静态成员???
        private void InitDict()
        {
            lock (synRoot)
            {
                dictCatalogMap = new HashMap();
                dictMap = new HashMap();
                dictListMap = new HashMap();

这里为什么不用clear?
看不懂


[其他解释]
单例? 你是不是少了什么?

我记得要私有化构造函数 才能保证单例啊 哥们
[其他解释]
堆栈溢出一般是递归调用溢出了递归栈大小,可以检查是否栈无终止,或者相互无穷调用。
[其他解释]
把getDictList这个方法获取改成加锁
[其他解释]
会不会是楼主 要从数据库获取的 数据太多!!

换言之,就是说 楼主的字典数据本身就太大!!??

——不过这也不能理解,少数用户不出问题,多数用户就出问题咧??!!
[其他解释]
,说堆栈溢出, 么样解决
[其他解释]
InitDict()   每次都会被 调用
导致:
                dictCatalogMap = new HashMap();
                dictMap = new HashMap();
                dictListMap = new HashMap();
每次都会被 新建新的字典;(旧字典留在内存中,交给了 内存回收器)

导致:
                新的3个字典都会被再次赋值;(内存中就会添加新数据)



——————————————————————————————
内存回收器不会频繁工作;
但是你每次都会新建新 字典,添加新数据,旧数据 直接就给 去掉引用了;

内存 不爆掉才怪呢!!!






[其他解释]
不好意思,看错了.....
——收回上面的误人误己的言论。。。。
[其他解释]
刚才看错了;

收回上面误人误己的言论.....
[其他解释]
因为下面做了判断,不要紧,感谢关心
[其他解释]
我看了一下代码——代码在本质上没有明显的内存泄漏情况;

我也不知道楼主说的 人多的时候是什么时候;
也不知道  每初始化一次,需要浪费多少内存——初始化多少次就会内存溢出.....


现在能够教楼主做的就是这个了:

 lock (synRoot)
 {
     if (dictCatalogMap.Count == 0)  //在多线程并发时,可能1线程完成初始化,2线程也近来要完成初始化,这时唯一一个多线程可能需要控制的地方;
     {
         //你的代码
     }
 }



[其他解释]

private void InitDict()
        {
            lock (synRoot)
            {

             这里少了一个判断语句.  当 N个线程同时调用 InitDict 后,  谁先获得锁谁就先执行完LOCK,然后释放锁,交给下一个线程. 下一个线程继续执行 InitDict ,获得锁,又执行初始化....

所以你这里你锁定后应该多一个判断,判断是否已经初始化了.



写完代码,你可以弄个多线程访问数据测试一下.
[其他解释]
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频繁重启
[其他解释]
IIS频繁重启
[其他解释]
楼上说的好像是很有道理,我先试试
[其他解释]
自己调自己,不死也难?
[其他解释]

引用:
    public class DictManager
    {
        private static DictManager instance = new DictManager();

还是感觉你的这个成员,造成了逻辑上的死循环,你自己看看吧。


这行代码怎么看 都是 单例模式;我怎么看不出调用了自己就是死循环的??!
[其他解释]
上面的代码已经按你们的改掉了,IIS还是有报


为应用程序池 'XXX' 提供服务的进程在与 World Wide Web Publishing 服务通信时遇到致命错误。进程 ID 为 '2088'。数据字段包含错误号。
[其他解释]
再说了

你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(){}

要这样啊!
[其他解释]
已经改成如下代码了,且可以确保类不是通过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();


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

可能理解的不对
[其他解释]
引用:
单例? 你是不是少了什么?

我记得要私有化构造函数 才能保证单例啊 哥们


私有构造函数只是为了不让外部 生成对象
——只要楼主 不在外部实例化对象,其实和 单例 性质一样好吧!!
[其他解释]
引用:
引用:

public class DictManager
{
private static DictManager instance = new DictManager();

还是感觉你的这个成员,造成了逻辑上的死循环,你自己看看吧。


这行代码怎么看 都是 单例模式;我怎么看不出调用了自己就是死循环的??!

没有私有的构造函数,还有类没有封闭。多实例不就完蛋了。
[其他解释]
unlock怎么个说法,怎么写
[其他解释]
多谢大家的回复,可能把大家误导了,昨天把代码又查了一遍,发现几年前写的一个库有问题,导致堆栈溢出
------其他解决方案--------------------


又看了看,改完后的,建议把getDictList这个方法获取改成加锁的吧。你返回了一个单例的成员中的引用类型数据给一堆人用,一定要加锁。
[其他解释]
楼主,我也是一样的问题,你的是啥原因,怎么解决的,能指点下么

热点排行