限制RAM的使用。(C#NET)
有大约100Mb的巨大文件。 我想把它们加载到内存(RAM),处理并保存到某个地方 同时,我希望内存使用存在限制。例如,100Mb,我的应用程序使用的内存不超过此限制。如果超过限制,则文件将被处理为零件 我的理解是:限制RAM的使用。(C#NET),c#,ram,limiting,C#,Ram,Limiting,有大约100Mb的巨大文件。 我想把它们加载到内存(RAM),处理并保存到某个地方 同时,我希望内存使用存在限制。例如,100Mb,我的应用程序使用的内存不超过此限制。如果超过限制,则文件将被处理为零件 我的理解是: var line = file.ReadLine(); var allowed = true; while( allowed && line != null ) { var newObject = new SomeObject( line ); li
var line = file.ReadLine();
var allowed = true;
while( allowed && line != null )
{
var newObject = new SomeObject( line );
list.add( newObject );
// Checking the memory
allowed = CheckUsedMemory();
line = file.ReadLine()
}
如何限制RAM的使用?
如何实现CheckUsedMemory方法?
多谢各位
UPD
谢谢大家的建议。您可以尝试以下方法:
long usedMemory = GC.GetTotalMemory(true);
或
第一种方法将强制对内存进行垃圾收集(清理),因此速度较慢(毫秒)
然后阅读以下内容,查看您的机器有多少内存:
请记住,如果您作为32位应用程序运行,您不能使用所有内存,其他进程可能正在使用内存 您无法真正限制内存使用。您只能限制保留的内存量。剩余内存是否被释放取决于垃圾收集器 因此,我建议您只关注当前正在缓冲的行数(最好是字符数),然后再处理它们
在评论中,人们建议你应该逐行阅读文件。假设您能够一次处理一行文件,这是一个非常好的建议。操作系统无论如何都会缓存文件,这样您就不会损失任何性能。看起来您希望逐行处理文件,但这可能有助于您了解,在.NET 4中,您可以使用它,它允许您首先稀疏地访问大文件,感谢您了解内存消耗情况。要是更多的程序员能这么体贴就好了 其次,我不想麻烦了:也许用户希望您的应用程序运行得尽可能快,并且愿意消耗8000兆的内存以使结果快5%。让他们来。:) 但是,如果在进程中强制进行更多磁盘访问,人为限制应用程序占用的内存量可能会大幅增加处理时间。如果有人在内存受限的系统上运行,他们很可能已经有了用于交换的磁盘流量——如果您在真正使用完内存之前人为地转储内存,那么您只会进一步增加磁盘IO,从而妨碍交换。让操作系统来处理这种情况 最后,您在这里编写的访问模式(顺序,一次一行)非常常见,毫无疑问,.NET设计人员已经投入了大量的精力,将这种模式的内存使用降至最低。将对象以部分的形式添加到内部树是一个不错的主意,但是很少有应用程序能够从中真正受益。(合并排序是一个很好的应用程序,它从部分处理中获益匪浅。) 根据您对已完成的对象列表所做的操作,您可能无法同时处理整个列表。或者,您可能会从将其拆分中受益匪浅。(如果你能很好地描述你的数据处理问题,那么也许你会从把事情分开中获益。)
在任何情况下,我都会对使用“内存”作为决定何时中断处理的基准有点怀疑:我宁愿使用“1000行输入”或“十级嵌套”或“运行五分钟的机床”或基于输入的东西,而不是消耗内存的副作用。正常的过程不是加载内存中的所有内容,而是将文件分块读取、处理并保存。如果出于某种原因,您必须将所有内容都保存在RAM中(比如排序),那么您很可能需要投资更多的RAM 这是您使用的算法的问题,因此问题应该是如何在不使用太多内存的情况下解决特定任务 将告诉您正在使用的内存量
现在100MB内存已经不多了。将其读入内存、处理并将其放回磁盘可以非常快。请记住,无论如何,您都无法避免将它从磁盘复制到内存,再复制回磁盘。使用StringBuilder(而不是字符串)保存它不一定会给应用程序增加太多开销。在一次操作中写入100MB肯定比一次写入一行要快。100MB的内存使用量并不大……一个巨大的文件将以GB而不是MB为单位……为什么需要在内存中处理这些文件?我这样问是因为不知道为什么逐行方法是不可行的,就不可能讨论是否可以加载和处理文件块。每当
allowed
为false时,该代码都会漏掉一行。我甚至会添加另一个问题:如果有一行1gb长的单行,会发生什么?还是2gb?还是3gb?如果你是“防御式”编程,那么你必须编写自己的读线(可能是一个分块版本,一次读取4k,按行尾拆分,返回拆分,但返回最后一个,保存最后一个,将其合并到下一个块的第一行)上一次我有一个原始格式[csv]的数据库,它拥有120 MB的空间。当我在浏览器中打开它们时,一切都不起作用。我恢复了我的系统,因为在那之后,我系统中的每个应用程序都崩溃了,甚至是大大小小的。
long usedMemory = GC.GetTotalMemory(false);