读书人

急求上面的代码引起的堆栈溢出的原因

发布时间: 2012-12-17 09:31:40 作者: rapoo

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


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这个方法获取改成加锁的吧。你返回了一个单例的成员中的引用类型数据给一堆人用,一定要加锁。
[其他解释]
楼主,我也是一样的问题,你的是啥原因,怎么解决的,能指点下么

读书人网 >C#

热点推荐