简体   繁体   English

concat two byte []返回System.OutOfMemoryException

[英]concat two byte[] returns System.OutOfMemoryException

I have a problem with concat two byte[]. 我有concat两个字节[]的问题。 One of them have more than 300,000,000 byte. 其中一个有超过300,000,000字节。 It's throwing exception of type System.OutOfMemoryException . 它抛出System.OutOfMemoryException类型的异常。

I use this code : 我用这个代码:

byte[] b3 = by2.Concat(by1).ToArray();

anybody can help me 任何人都可以帮助我

Because of Concat call ToArray know nothing about how big the result array has to be. 因为Concat调用ToArray对结果数组的大小一无所知。 It can't create proper, big array and just fill it with data. 它无法创建正确的大数组,只需填充数据即可。 So it creates small one, then when it's full creates new one with twice the size, etc. over and over again as long as there is more data to fill. 所以它会创建一个小的,然后当它完全创建一个大小两倍的新的,等等,只要有更多的数据要填充。 This way you need much more memory then just theoretical (b1.Length + b2.Length) * 2 . 这样你需要更多的内存,然后只需要理论(b1.Length + b2.Length) * 2 And things get even more tricky, because after certain point these big arrays are allocated on LOH, and are not collected that easily by GC as normal objects. 事情变得更加棘手,因为在某些点之后这些大数组被分配在LOH上,并且不像GC那样容易收集到普通对象。

That's why you should not use ToArray() in this case and do it the old-fashioned way: allocate new array with size equals combines sizes of source arrays and copy the data. 这就是为什么你不应该在这种情况下使用ToArray()并以老式方式执行:分配大小等于组合源数组大小的新数组并复制数据。

Something like: 就像是:

var b3 = new byte[b1.Length + b2.Length];
Array.Copy(b1, b2, b1.Length);
Array.Copy(b1, 0, b2, b1.Length, b2.Length);

It does not guaranty success, but makes it more likely. 它不保证成功,但更有可能。 And executes much, much, much faster then ToArray() . 并执行比ToArray()快得多,快得多。

When working with that amount of data, I think you should be working with streams (this of course depends on the application). 使用这些数据时,我认为您应该使用流(这当然取决于应用程序)。

Then you can have code that works on the data without requiring it all to be loaded in memory at the same time, and you could create a specialized stream class that acts as a concatenation between two streams. 然后,您可以拥有适用于数据的代码,而无需将所有代码同时加载到内存中,您可以创建一个专门的流类,充当两个流之间的串联。

Well, the error message taks for itself, you don't have free continuous ~550Mb of RAM. 好吧,错误消息为自己,你没有自由连续~550Mb的RAM。 Maybe it's just too fragmented. 也许它太分散了。

Well.. you know, requesting from the system a continuous block of ~600meg - I'm not suprised. 嗯..你知道,从系统请求连续的~600meg块 - 我并不感到惊讶。 It is quite a large block itself, and provided that you must also have the source arrays in the memory, that's over 1GB of raw data chunks.. 它本身就是一个很大的块,并且你必须在内存中拥有源数组,这超过了1GB的原始数据块。

You should probably start thinking about other data structures, or try to keep them as files and map them to memory edit: memmapping a whole file needs the same contiguous area in address space, so it solves nothing. 您应该开始考虑其他数据结构, 或者尝试将它们保存为文件并将它们映射到内存 编辑:memmapping整个文件在地址空间中需要相同的连续区域,因此它不会解决任何问题。 This answer will be deleted. 此答案将被删除。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM