现在接触到一个项目,其中会对较大数据量的一维数组进行较为频繁的读入操作.(数组大小在500M以上).
在程序运行一段时间后,再次进行数据读入操作,会出现内存溢出的异常,观察系统内存并没有显著上升,初步判断为当前内存中已没有500M以上连续空间供当前数据的载入.如何能避免类似情况发生呢- -?

解决方案 »

  1.   

    用泛型不行么
    ArrayList sa = new ArrayList();
      

  2.   

    内存不是被耗尽的,系统内存没有显著上升.
    比如在我机子上看的话,总内存2G,现在占用内存1G,我再开一个500M左右的空间就有可能不成功,估计是没有连续空间供数组使用了.
    多次载入的不是同一组数据,不需要的数据也会被释放.
      

  3.   

    在加载数组之前显示调用
    GC.collect();
      

  4.   

    在重新说一下问题好了,系统内存还是足够的,但无法new一个足够大的一位数组(N百兆).
    个人判断为系统内存中不存在足够大小的连续空间供该一维数组使用.
    现在想问下有没有什么方法能令系统中的内存有足够的连续空间,供我的一维数组使用?
      

  5.   

    .NET Memory Profiler 3.1 , 你用下这个工具,跟踪下内存变化。
    我觉得你的目测观测手段可能不行。        //Force garbage collection.
            GC.Collect();        // Wait for all finalizers to complete before continuing.
            // Without this call to GC.WaitForPendingFinalizers, 
            // the worker loop below might execute at the same time 
            // as the finalizers.
            // With this call, the worker loop executes only after
            // all finalizers have been called.
            GC.WaitForPendingFinalizers();很多情况下,gc 还没来得急回收,新的再申请。内存就会直线上升。
    强制回收后,再加上GC.WaitForPendingFinalizers();等待回收完毕后,在继续
      

  6.   

    这种情况可以不用数组,改用List<T>,这是链表,不需要连续的空间也可以存储大量数据
      

  7.   

    用泛型或ArrayList或许会好些。
      

  8.   

    应该跟数组还是集合本身无关,在 vb6 的 collection 中也存在同样的问题,通常数组不应初始化为很大,也不适合与存放大量数据在内存中,需要使用 cash.
      

  9.   


    数组也是引用类型,存放在堆上所有数组都是Arry类的实例,忘记了数组需要new吗
      

  10.   

    目前创建超过85K的对象将放到大对象堆(Large Object Heap)中。由于碎片整理需要额外开销,目前CLR并没有整理Large Object Heap。所以很有可能,就象你怀疑的,程序运行一段时间后没有500M以上连续空间可供分配了。可能的解决方法就是一开始就分配好大数组(比如两个),随后重复利用,而不是销毁重建。Large Object Heap可参见MSDN杂志文章:
    Large Object Heap Uncovered
      

  11.   


    数组是引用类型,对象数据也存储在托管堆中,这没错,分配给改对象的实例引用存储在堆栈中,堆栈存储的是改对象在托管堆中的地址,要不你如何通过代码确定你的对象数据在哪?
    数组本身占用堆栈,每个数组的元素同样会占用堆栈。这跟递归调用层数太多导致堆栈溢出是一样的道理,没有可分配的堆栈来存储对象的引用,堆数量会非常庞大,因为 Windows 本身可以增大虚拟内存,而堆栈是有限的。通常情况下其引发 OutOfMemoryException 异常。
      

  12.   

    建议楼住这样
    1。自己写个类  通过对于文件系统操作 还减少 可能的缓冲区益处
    2。定义一个类 继承IDispose 让.NET 及时回收 内存资源
      

  13.   

        public partial class Form2 : Form
        {
            private Class1[] c1;
            private Class1[] c2;        class Class1
            {
                int x, y;
                public Class1()
                {
                    x = 1;
                    y = 2;
                }
            }        public Form2()
            {
                InitializeComponent();
            }        private void button1_Click(object sender, EventArgs e)
            {
                c1 = new Class1[99999999];
                c2 = new Class1[99999999];
            }
    }点几次按钮马上 OutOfMemory。
      

  14.   

    用一维数组问题还是无法解决,暂时用集合(List)+数组的方式将大数组分段保存,确保空间能够开辟.问题是用list等集合类进行数据操作的时候,在效率上完全不能与一维数组相提并论.运行时间上差了近3倍....这还是很多运算与数据获取无关的情况下- -!
      

  15.   


    大哥,你的一句话,查了我好几天。
    http://msdn.microsoft.com/en-us/library/ms379570(VS.80).aspxMS上说的很清楚,Array 的Element,无论是值类型还是引用类型,都是分配在Managed Heap上的,上面的图。至于你下面的举例OOM,应该是发生在Heap上的,而不是stack上:
    http://dev.csdn.net/article/19/19679.shtm
    不过内存不是无限的,堆的空间分配光了怎么办?CLR在分配内存的时候,如果发现堆中的空闲空间不足时,就会启动无用空间回收。GC将堆中不再被使用的对象占用的内存释放掉,然后将堆整理,使其剩下连续的空间以待分配,当然如果没有可以释放的对象或者释放后内存还是不够的话,就抛出OutOfMemoryException异常。不知道我说的是否有错误,请指教。。