【问题标题】:C# OutOfMemoryException when multiple threads are inserting data into a list with same time lagC# OutOfMemoryException 当多个线程将数据插入到具有相同时间延迟的列表中时
【发布时间】:2013-12-18 10:06:27
【问题描述】:

我遇到了一个奇怪的现象,当线程(几乎同时启动)在插入数据之前睡眠相同且固定的时间时,会发生异常。但是如果它们在插入数据之前每个都随机休眠,则不会发生内存异常。这种情况反复发生。

列表每次崩溃时不超过 2000 个项目(每个项目大约只有 10 个字节)。这似乎没有超出内存限制。

如果每个线程都这样休眠:

Thread.Sleep((int)((new Random(DateTime.Now.Second)).NextDouble() * 10000));

它不会使应用崩溃,而如果睡眠时间相同且固定时间:

Thread.Sleep(6000);

它会崩溃。

更新: 抱歉信息不完整,感谢您的回答。 我在编辑列表时确实有一个储物柜(无论何时何地)。

并且我用我真正耗时的工作(显然完成时间不同)替换了“睡眠”,OutOfMemory 异常再也没有发生。

所以这是抽象的问题: 一些线程(大约 30 个)同时启动(几乎)并同时休眠,然后同时(几乎)对列表(带锁)执行某些操作。这将导致 OutOfMemoryException。 但是如果让它不那么同时(睡觉/做不同时间的工作),就可以了。

是的,高同时性会导致一些问题,但为什么是 OutOfMemory?只有 30 个线程,每个线程只更新几个字节到一个列表。 谢谢。

抱歉堆栈跟踪信息丢失。 :(

【问题讨论】:

  • 请发布重现问题的最小代码。
  • 如果您想创建伪随机数,您应该创建Random 类的单个实例,然后重复调用NextDouble。您的代码生成的数字每秒只会发生变化。
  • OutOfMemoryException 的堆栈跟踪是什么?您使用的是什么类型的列表? List<T>? T(元素类型)是什么?特别是T 是值还是引用类型?如何将元素添加到列表中?你用了多少线程?

标签: c# multithreading memory


【解决方案1】:

问题是多个线程同时访问同一个元素,这会导致不可预知的错误。要同步线程试试这个

lock(yourListObject)
{
   yourListObject.InsertData(data);
}

编辑:你应该看看lock statement

【讨论】:

  • 抱歉信息不完整。我确实在代码中有锁定机制。我只是觉得奇怪为什么会发生我们的内存异常。
【解决方案2】:

您使用的列表类型不是线程安全的。您可以使添加和访问代码线程安全或使用线程安全列表类型。没有代码(类型)很难说你应该做什么。

【讨论】:

    【解决方案3】:

    显然,当所有线程尝试同时更新列表时,插入代码中的某些内容会导致高内存负载。也许一些锁定机制?或者尝试将数据插入可能锁定的资源中的任何递归或循环?

    【讨论】:

    • 抱歉信息不完整。请检查更新的问题。谢谢。
    【解决方案4】:

    尝试使用ConcurrentBag 代替 List 来查看您的问题是否来自列表上的并发访问。

    【讨论】:

    • 感谢您的建议。我应该考虑线程安全的数据结构。但我主要好奇为什么内存不足异常。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-10-31
    • 1970-01-01
    • 2017-05-26
    • 1970-01-01
    • 2014-04-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多