我们在ASP.Net 4.0网站上遇到过每日OutOfMemoryExceptions。我们怀疑其中一个问题是LOH碎片,所以我们一直在寻找可以更有效地分配内存的代码更改。
例如,我们正在生成一个我们想要返回浏览器的大字符串(2mb)。分页数据不是一种选择。
更有效率:
Response.Write(bigString)
或Response.Write(smallString)
如果我按照选项1那么我有一个大字符串占用LOH上的空格,然后被复制到Response对象的内部缓冲区。所以这似乎我现在至少暂时在LOH上有两个大块。
如果我遵循选项2,那么我正在处理大量收集垃圾的小字符串,并且只处理LOH上的一个大块用于Response对象的缓冲区。
所以在我看来,选项2更好。
我是否正确理解了这一点?
服务器有4GB的Ram并运行Windows 2003 32位。这是服务器上运行的唯一站点。因此每个进程都有一个4GB的地址空间,但只有2GB可用。当虚拟字节大约达到1.8Gb时,我们开始收到OOM错误,然后我们回收解决问题大约24小时的站点。专用字节在500-800mb之间变化。我不认为问题是我们的物理内存耗尽。
答案 0 :(得分:1)
在不知道实施的情况下,我的回答可能比我希望的有所帮助。不过,我会冒险尝试。
如果是我,我会采用两种策略:
答案 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。