全部博文(372)
2012年(372)
分类: 虚拟化
2012-03-25 19:51:03
这篇文章阐述了当使用处理大型数据集时经常触发的模棱两可的异常,并且介绍了一个类——MemoryTributary,他可以用来替代.NET内置的MemoryStream,并且能够支持大型数据的处理。
背景当试图使用MemoryStream处理较大数据(in the order of tens of MB)时,它通常会引发OutofMemoryException异常。这是不是因为,正如其命名的那样,超出了系统内存的限制了呢?但实际上那都是进程的虚拟地址空间。
当进程从Windows申请内存的时候,内存管理器并没有从RAM中分配地址空间,但是“页面”——存储块(通常是4KB)可以存在于RAM、磁盘或者任何内存管理器能够决定存储它们的地方。页面映射到进程的地址空间,因此,假如当进程试图从[0xAF758000]开始访问内存时,它实际上是在访问[第496页]开始的地方,无论是否恰好是[第496页]。可以为进程分配任何大小的足够的内存,只要磁盘空间充足,并可以将其中的一大部分作为虚拟地址空间,这适用于任何时候。在这个分配过程中会产生大量的小碎片(这里是指存储块)。
这是因为进程地址空间是支离破碎的:大部分都被操作系统占用,诸如应用程序映像、库以及其他预分配的空间等。一旦内存管理器分配了所请求的相当于页面大小的内存,就必须在进程内映射到(虚拟)地址空间。而当剩余的地址空间中没有足够的连续空间时,页面就无法被映射,从而导致内存分配失败,也就引发了OutofMemoryException异常。
这个过程并没有耗尽空间和地址,它运行在连续的地址上。要看到这个(如果你在用64位系统),在x86目标平台下编译如下程序并运行它,然后再编译为x64目标平台,看看两者的区别。
.NET当前实现的MemoryStream使用了一个字节数组作为后备存储。当要写入的内容超出数组长度的时候,容量就会自动扩展一倍(老陈注:这是.NET数组自身的内存分配机制)。根据程序这种行为,基于这种后备存储机制的MemoryStream会很快就需要比可用虚拟地址空间更多的内存。
代码用例这个解决方案并不是申请更多更大的连续内存去存储流中包含的数据。MemoryTributary内部使用了4KB的动态集合来作为后备存储,实现按需分配。
MemoryTributary从派生,因此可以像使用其他Stream一样的使用它,类似于MemoryStream。
MemoryTributary不过是想作为MemoryStream的一个替代方案,但不是可以在任何情况下都可以替代MemoryStream的,以下是一些注意事项:
使用MemoryTributary要注意以下几点:
在容量和速度上,MemoryStream和MemoryTributary都是很难预料的,因为这依赖于很多因素。一个很重要的因素是当前进程的内存碎片——一个进程分配了大量内存将会导致大量内存碎片的发生。
容量流 | 平均崩溃临界值(MB) |
---|---|
MemoryStream | 488 |
MemoryTributary | 1272 |
流测试执行时间比对 (ms) | ||||
读写容量 |
MemoryStream | MemoryTributary (4KB Block) |
MemoryTributary (64KB Block) |
MemoryTributary (1MB Block) |
10 | 10 | 13 | 11 | 7 |
3 | 5 | 3 | 3 | |
3 | 6 | 3 | 3 | |
3 | 5 | 3 | 3 | |
4 | 5 | 3 | 3 | |
3 | 6 | 3 | 3 | |
100 | 100 | 148 | 123 | 52 |
34 | 54 | 42 | 35 | |
34 | 48 | 35 | 34 | |
35 | 47 | 36 | 35 | |
34 | 48 | 36 | 35 | |
35 | 51 | 35 | 35 | |
500 | 516 | 390 | 290 | 237 |
167 | 222 | 184 | 170 | |
168 | 186 | 154 | 167 | |
167 | 187 | 151 | 168 | |
167 | 186 | 151 | 168 | |
167 | 185 | 153 | 168 | |
1,000 | 1185 | 1585 | 1299 | 485 |
347 | 547 | 431 | 344 | |
343 | 463 | 350 | 345 | |
338 | 462 | 350 | 345 | |
3377 | 461 | 349 | 345 | |
339 | 465 | 351 | 343 |
请到原文地址下载: