我写了个Windows 窗口程序.
其中用到一个很大的HashTable对象,要装1亿个关键字。
我测了一下以下代码,
Hashtable childNodes = new Hashtable();
for (int i = 0; i < 100000000; i++)
{
     childNodes.Add(i, "aaaaaaaaaaa");
}我的电脑 4G 内存,每次当它执行到1720万左右个关键字时,抛出 xception of type 'System.OutOfMemoryException' was thrown.
这是我看一下任务管理器,这个程序的进程大概只用了525M 左右内存。我的电脑:Windows XP Pro; 32位的机器; 4G 内存; 
我用: VS2010
请问,为什么在内存还有很多的情况下,.NET这么早抛出错误?
该如何解决这个问题?
是不是可以在那里进行必要设置?急!谢谢大家!!!

解决方案 »

  1.   

    那肯定要内存溢出啊。
    for训话里面,执行n调后,调用一下下面的这段,试试。                System.Diagnostics.Process p = System.Diagnostics.Process.GetCurrentProcess();
                    if (p.WorkingSet > 40960000)
                    {
                        p.MaxWorkingSet = p.MaxWorkingSet;
                    }
      

  2.   

    for循环里面,执行n条后,调用一下下面的这段,试试。搜狗拼音啊... ...
      

  3.   

    去搜索一下持久字典。
    目前我用别人实现的C#版B+树算法来做的。
    http://sourceforge.net/projects/bplusdotnet/
      

  4.   

    就说明不够了, Hashtable的索引不知道是否有上限阿~~怎么设计程序也不合理阿,可以使用文件的方式来保存,如果是用来做字典的话,可以考虑楼上的持久字典,速度和效率平衡
      

  5.   

    调用垃圾回收,并等待回收完毕后继续执行试一下。
    测试了几次,没办法等到异常,太久了,忙…
    你自己试试这样,清理掉堆栈调用的垃圾试试,当你add时候,系统应该做了不少事情,这些内存回收可能会让你的程序跑的更久一点。Hashtable childNodes = new Hashtable();
    for (int i = 0; i < 100000000; i++)
    {
        childNodes.Add(i, "aaaaaaaaaaa");
        if (i % 100 != 0) continue;
        GC.Collect();
        GC.WaitForFullGCComplete();
    }
      

  6.   

    p.MaxWorkingSet = p.MaxWorkingSet;的意思是扩大当前进程的最大工作内存...
    不过我的感觉是Hashtable对象内存溢出了,
    你看下这片纹章
    http://topic.csdn.net/t/20050527/15/4040275.html
      

  7.   


    为什么是
    p.MaxWorkingSet = p.MaxWorkingSet;
    等号2边怎么是相同的???
      

  8.   

    1亿个肯定要溢出了,hashTable为了防止碰撞,申请的内存要远大于集合元素的数量,以2G内存为例(进程寻址上限),HashTable也就能承受2000万左右的数据量。解决办法有如下几种:
    1、用64位操作系统配合64位机器(对于企业来讲是最简单的方案,就是花钱的事儿)
    2、程序弄复杂一些,改为多进程,自己写个算法分配不同的数据到不同进程,不过4G内存还是不够。
    3、用二叉树别用HashTable,比如SortedSet,可以节省一些内存,但速度会慢,同样受2G内存的限制,1亿肯定不行。
    4、修改整个方案,别都在内存中弄,不过速度会更慢。
      

  9.   

    32位机的进程只能用来2G内存。
    因为动态的hash表要重组,重组的地址空间是原地址空间的2倍(不包括内容),所以原地址空间大于可用空间1/3的时候就会内存不足了。解决这个问题可以在new的时候指定一个极限容量(可以用二分法测试)不让它重组。就算这样要装1亿关键字也很难。
    如果楼主的关键字固定不变而且平均长度在20字符左右的话,可以考虑自己写一个静态hash类。
      

  10.   

    当然适用于静态hash的情况,也可以用排序+二分方法代替,只是运行效率差一些。
      

  11.   

    几乎没有更好的办法解决这一问题,这是NET是缺限。。不象非托管代码可以自已回收内存
      

  12.   

    除了一个英文字符占两字节,其它的与是否.net关系不大吧。