【问题标题】:How to manage systemoutofmemory exception?如何管理 systemoutofmemory 异常?
【发布时间】:2019-04-29 06:20:52
【问题描述】:

我正在处理大约 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;

我希望我的 genericlist 会在 genericList 被填充后正常运行。但是vshost32.exe被抛出systemoutofmemory异常。

【问题讨论】:

  • 为什么你需要在你的内存/列表中加载 3 GB 的数据?您到底想达到什么目标,也许我们可以寻找更好的解决方案。请记住,清除列表@XXXmb 可能会为您解决问题,但可能会在内存较少的低规格设备上导致同样的问题
  • 实际上我对硬件没有任何限制。我使用的是 16gb Ram 和 500gb SSD。我以为我的硬件很容易运行。但不知何故,视觉工作室抛出 systemoutofexception 。我不明白。
  • 但是你为什么要首先这样做呢? saied 列表中实际存储了什么?
  • 因为我在 datagridview 上需要 3 gb。我将在 datagridview 顶部添加一些过滤器属性。我将处理 datagridview 上的数据,例如更新、删除或插入。但我想查看 datagridview 中的所有数据。否则我无法处理数据。
  • DataGridView 从未设计用于处理如此可笑的海量数据。我严重怀疑您是否真的需要一次所有 3GB 的内存数据。

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


【解决方案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. 将数据存储在内存缓存中,并仅将一两页绑定到数据网格源,缓存更适合此类数据,尤其是在您没有内存不足的情况下,它可以快速访问

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

【讨论】:

  • gc 甚至会触摸数据吗?有一个参考,所以我认为它不会收集它。如我错了请纠正我。另外,据我所知,手动调用垃圾收集器是不好的做法,不是吗?
  • @DenisSchaf 假设数据仍然被引用,GC 无法触及它,但是让我们假设 OP 释放它,GC 仍然不是确定性的,即使显式使用 GC API 并且这里可能 GC 没有时间推销在内存濒临OOM的时候,GC无法优化并且系统抛出异常。理想情况下,GC api 用于测试系统,显式等待挂起的终结器或生成集合,但不适用于生产代码。充其量我们可以使用Workstation或Server GC,这是一种配置
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-06
  • 1970-01-01
相关资源
最近更新 更多