如何管理系统内存不足异常?

时间:2019-04-29 06:20:53

标签: c# winforms memory-management out-of-memory stack-overflow

我正在处理大约3 gb的数据。它存储在Oracle数据库中。我的任务是在datagridview上列出此数据。这就是为什么我创建一个类来存储此数据,然后使用此genericList来推送datagridview的数据源的原因。但是,在ram中处理了大约1300行数据后,代码返回了“ stackoutofmemory”异常。程序停止运行。

在上载1300 mb数据后,我尝试清除了genericList数据,并使用垃圾回收在ram中清除了数据。但这没有用。 vshost32.exe仍然增加。

var dataList = cmd=........... // get dataList from DB
list<class> dataList2 = new list<class>();

foreach(var data in dataList) {
     dataList2.add(new class{
    ...........//fill the DataList2
});

datagridview.datasource = datalist2;

我希望我的类属列表将在填充类属列表之后正常运行。但是vshost32.exe被抛出systemoutofmemory异常。

1 个答案:

答案 0 :(得分:1)

您正在处理几个问题,让我们一一讨论:

  

我正在处理大约3 GB的数据。它存储在Oracle数据库中。我的任务是在datagridview上列出这些数据

首先,没有人可以一次查看3 GB数据,这就是为什么它总是部分可见的原因,这就是为什么对数据进行分页以提供有限的页面视图的原因

  

这就是为什么我创建一个类来存储此数据,然后使用此genericList推送datagridview的数据源的原因

像datagridview的数据源这样的大多数数据结构都有内部限制,它们并不是要存储大量数据,否则会破坏数据结构或使性能变得很差

  

在上载1300 mb数据后,我尝试清除了genericList数据,并使用垃圾回收在ram中清除了数据。但这没有用。 vshost32.exe仍然增加。

这里有几点,不确定在1300 MB时如何清除数据,但是您肯定使用的是32位进程,该进程的用户限制为2 GB,因此OOM越过该限制。剩下的2 GB用于内核进程,您可以为用户进程调整为最大3 GB,但是通常来说,您正在处理数据结构的内部限制,或者纯粹是您假设清除任何内存,因为GC特别不确定,它很快就会越过边界

  

解决方案是什么?

  1. 在64位系统上使用64位进程,这将确保“内存不足”异常消失,因为现在的内存限制为2 ^ 64字节= 16 ExaBytes。您可以确保进程/二进制文件是64位兼容的
  2. 将数据存储在内存缓存中,并且仅将一两个页面绑定到数据网格源,缓存更适合此类数据,尤其是在您没有RAM的情况下,它的快速访问权限

大多数情况下,在64位进程中,它永远不会内存不足,因为即使系统仅为用户进程分配了一半的内存,通常也没有哪个系统的RAM高于16 ExaBytes