有趣的 OutOfMemoryException 与 StringBuilder [英] Interesting OutOfMemoryException with StringBuilder

查看:25
本文介绍了有趣的 OutOfMemoryException 与 StringBuilder的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要在循环中不断构建大字符串并将它们保存到数据库中,该数据库目前偶尔会产生 OutOfMemoryException.

I have the need to continuously build large strings in a loop and save them to database which currently occasionally yields an OutOfMemoryException.

这里的基本情况是我使用 XmlWriter 和基于一些数据的 StringBuilder 创建一个字符串.然后我从外部库调用一个方法,将这个 xml 字符串转换为其他字符串.之后,转换后的字符串将保存到数据库中.对于不同的数据,整个过程在循环中重复完成大约 100 次.

What is basically going on here is I create a string using XmlWriter with StringBuilder based on some data. Then I call a method from an external library that converts this xml string to some other string. After that the converted string is saved to the database. This whole thing is done repeatedly in a loop about a 100 times for different data.

字符串本身并不太大(每个小于 500kByte)并且进程内存在这个循环中没有增加.但是,偶尔我会在 StringBuilder.Append 中得到一个 OutOfMemeoryExcpetion.有趣的是,此异常不会导致崩溃.我可以捕获该异常并继续循环.

The strings by itself are not too big (below 500kByte each) and the process memory is not increasing during this loop. But still, occasionally I get a OutOfMemeoryExcpetion within StringBuilder.Append. Interestingly this exception does not result in a crash. I can catch that exception and continue the loop.

这里发生了什么?为什么我会得到 OutOfMemoryException 尽管系统中仍有足够的可用内存?这是一些 GC 堆问题吗?

What is going on here? Why would I get an OutOfMemoryException although there is still enough free memory available in the system? Is this some GC heap problem?

鉴于我无法避免转换所有这些字符串,我该怎么做才能使这项工作可靠?我应该强制执行 GC 收集吗?应该将 Thread.Sleep 放入循环中吗?我应该停止使用 StringBuilder 吗?遇到 OutOfMemoryException 时是否应该简单地重试?

Given that I can't circumvent converting all these strings, what could I do to make this work reliably? Should I force a GC collection? Should put a Thread.Sleep into the loop? Should I stop using StringBuilder? Should simply retry when confronted with a OutOfMemoryException?

推荐答案

有内存但没有可以处理字符串生成器大小的连续段.你要知道,每次字符串生成器的缓冲区太短,它的大小就会增加一倍.如果您可以(在 ctor 中)定义构建器的大小,那就更好了.处理大量对象后,您可以调用 GC.Collect().

There is memory but no contiguous segment that can handle the size of your string builder. You have to know that each time the buffer of the string builder is too short, its size is doubled. If you can define (in the ctor) the size of your builder, it's better. You MAY call GC.Collect() when you are done with a large collection of objects.

实际上,当你有一个 OutOfMemory 时,它通常显示一个糟糕的设计,你可能使用硬盘驱动器(临时文件)而不是内存,你不应该一次又一次地分配内存(尝试重用对象/缓冲区/...).

Actually, when you have an OutOfMemory, it generaly shows a bad design, you may use the hard drive (temp files) instead of memory, you shouldn't allocate memory again and again (try to reuse objects/buffers/...).

我强烈建议您阅读这篇文章 内存不足"不指物理内存,来自 Eric Lippert.

I STRONGLY advice you to read this post "Out Of Memory" Does Not Refer to Physical Memory from Eric Lippert.

这篇关于有趣的 OutOfMemoryException 与 StringBuilder的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆