一旦构建一个大字符串并将其传递给response.write或为每个字符调用response.write,它是否更有效

时间:2014-06-03 22:17:04

标签: c# asp.net out-of-memory memory-fragmentation

我们在ASP.Net 4.0网站上遇到过每日OutOfMemoryExceptions。我们怀疑其中一个问题是LOH碎片,所以我们一直在寻找可以更有效地分配内存的代码更改。

例如,我们正在生成一个我们想要返回浏览器的大字符串(2mb)。分页数据不是一种选择。

更有效率:

  1. 在StringBuilder中构建字符串,然后只调用Response.Write(bigString)
  2. 通过重复调用Response.Write(smallString)
  3. 来逐字记录字符串

    如果我按照选项1那么我有一个大字符串占用LOH上的空格,然后被复制到Response对象的内部缓冲区。所以这似乎我现在至少暂时在LOH上有两个大块。

    如果我遵循选项2,那么我正在处理大量收集垃圾的小字符串,并且只处理LOH上的一个大块用于Response对象的缓冲区。

    所以在我看来,选项2更好。

    我是否正确理解了这一点?

    服务器有4GB的Ram并运行Windows 2003 32位。这是服务器上运行的唯一站点。因此每个进程都有一个4GB的地址空间,但只有2GB可用。当虚拟字节大约达到1.8Gb时,我们开始收到OOM错误,然后我们回收解决问题大约24小时的站点。专用字节在500-800mb之间变化。我不认为问题是我们的物理内存耗尽。

2 个答案:

答案 0 :(得分:1)

在不知道实施的情况下,我的回答可能比我希望的有所帮助。不过,我会冒险尝试。

如果是我,我会采用两种策略:

  1. 利用硬盘空间并写入存储在服务器上缓存目录中的文本文件(假设只有一个Web服务器)
  2. 使用旧式的Server.Execute(“〜/ filename.txt”);将文本文件内容吐出到您的页面上。

答案 1 :(得分:0)

答案可能取决于您如何构建“大型2Mb字符串”。 例如,使用StringBuilder类来连接内容,例如

,这是至关重要的
System.Text.StringBuilder sb = new System.Text.StringBuilder(256*1024);
sb.AppendText("some text");
sb.AppendText(myObject.name);
sb.AppendText("more text");
Response.Write(sb.ToString());

并且不要像这样使用字符串连接:

myString += "some text";
myString += myObject.name;
myString += "more text";

如果您使用后一种方法,我希望您可能会遇到消耗GB内存以创建一个2Mb字符串并不断与垃圾收集器作战。

当然,写入Response对象可能胜过两种技术,但是YMMV。