.NET 字符串与流 - 内存配置文件和特征

Posted

技术标签:

【中文标题】.NET 字符串与流 - 内存配置文件和特征【英文标题】:.NET Strings vs. Streams - Memory Profile and Characteristics 【发布时间】:2010-09-28 16:13:18 【问题描述】:

我需要从数据库 (nvarchar) 中提取大型 Unicode 文本字符串(例如 200Mb)并存储在内存中以进行处理。即我需要随机访问字符串的所有部分。

从严格以内存为中心的角度来看,使用 System.IO.MemoryStream 与 System.String 作为我的内存表示的优缺点是什么。

我正在尝试研究的一些因素是:

这些对象如何在 [假设的] 高度碎片化的低内存环境中发挥作用 不变性 内存中的实际大小 (如果流是 UTF8,我们是否几乎 减半) 还有其他我没有想到的对象吗?

我正在寻找关于这些点的清晰和建议,以及我没有想到的任何其他记忆注意事项?

注意:处理这些字符串可能有更好的方法,但此时我只是询问存储此类对象的内存考虑。

【问题讨论】:

有源代码的好示例吗?? 【参考方案1】:

从严格以内存为中心的角度来看,使用 System.IO.MemoryStream 与 System.String 作为我的内存表示的优缺点是什么。

我正在尝试研究的一些因素是:

这些对象如何在 [假设的] 高度碎片化的低内存环境中发挥作用

IMO,MemoryStream 仅在编码很简单(例如 ASCII、ISO-8859-X 等)时才有用。如果编码是 UTF-8 并且您有非 ASCII 字符,那么处理将变得更加困难。当然,MemoryStream 几乎肯定会消耗更少的内存,但除此之外没有太大区别。在底层,MemoryStream 使用字节数组,它也需要分配在连续的内存块中。

内存中的实际大小(如果流是 UTF8,我们是否将大小减半)

没错,使用纯 ASCII 字符,MemoryStream 将消耗等效字符串消耗的一半。

还有其他我没有想到的对象吗?
List<byte> // has a nicer interface for processing

字符串是如何存储在数据库中的? varchar 还是 nvarchar?

问候,

安德烈亚斯

【讨论】:

感谢 Andreas,字符串从数据库中以 nvarchar 形式出现。 你好安德烈亚斯。在 MSDN 上进一步阅读之后,我读到使用默认构造函数创建的 MemoryStream 是可调整大小的,因此这表明它不需要连续的内存块。这是一个公平的假设吗? 见:msdn.microsoft.com/en-us/library/… 在这种情况下,如果我没记错的话,那么使用 LINQ 或 ADO 就无法避免 System.String。所以至少当你加载数据时,你需要将整个字符串放入内存中。在进一步处理之前将其转换为字节数组 - 直到 GC 收集字符串 - 需要更多内存。 是的,通过 DataReader 可能是最好的。我猜你在多个块中读取 DB 字符串并将它们转换为 UTF-8,然后再将它们写入 MemoryStream,对吧?如果是这样,那么之前调用 MemoryStream.SetSize 将避免任何额外的分配和复制。【参考方案2】:

字符串与流的内存相当无关紧要。字符串是 utf-16,因此可能会涉及一个小的倍数,但由于涉及的卷,您最好将数据写入暂存文件。

要从数据库中读取数据,请使用流技术;即使用 IDataReader (ExecuteReader),它处于顺序模式,并读取字节/字符块。不要试图阅读整列。

此外,对于 SQL Server 2008,您可能希望查看文件流类型。

例子:

reading 大块/块 writing 大块/块

【讨论】:

以上是关于.NET 字符串与流 - 内存配置文件和特征的主要内容,如果未能解决你的问题,请参考以下文章

nodeJs文件系统(fs)与流(stream)

ASP.Net Worker 进程内存配置文件工具

struts2struts2中的流接收与流发送

C语言提高内容目录

JAVA基础篇—文件与流

Boost.Log 配置文件