Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#:管理大型内存缓冲区_C#_Memory Management_Pixels - Fatal编程技术网

C#:管理大型内存缓冲区

C#:管理大型内存缓冲区,c#,memory-management,pixels,C#,Memory Management,Pixels,我正在维护一个用C#编写的视频应用程序。 我需要尽可能多地控制内存分配/释放 用于大内存缓冲区(数百兆字节) 写入时,当需要释放像素数据时,像素缓冲区 设置为空。有没有更好的方法释放内存? 垃圾收集大型对象的成本高吗 谢谢 根据我的记忆,垃圾收集大型对象的成本非常高。据我所知,它们在分配时自动成为第2代(它们在大型对象堆中分配)。而且,由于它们很大,它们迫使频繁的第2代收集 因此,我宁愿为位图数组实现手动池,甚至使用非托管内存。拥有一些pool类,并将数组返回到像素/位图类的Dispose中。不

我正在维护一个用C#编写的视频应用程序。 我需要尽可能多地控制内存分配/释放 用于大内存缓冲区(数百兆字节)

写入时,当需要释放像素数据时,像素缓冲区 设置为空。有没有更好的方法释放内存? 垃圾收集大型对象的成本高吗


谢谢

根据我的记忆,垃圾收集大型对象的成本非常高。据我所知,它们在分配时自动成为第2代(它们在大型对象堆中分配)。而且,由于它们很大,它们迫使频繁的第2代收集


因此,我宁愿为位图数组实现手动池,甚至使用非托管内存。拥有一些pool类,并将数组返回到像素/位图类的
Dispose
中。

不要扔掉这样大的缓冲区,你拥有它是幸运的。视频提供了很多重复使用的机会。在确定不再需要缓冲区之前,不要丢失缓冲区。在哪一点上,它在何时被收集并不重要。

对于如此大的内存块(“数百兆字节”),应该相对容易准确地知道谁在哪里使用它们(无论如何,在内存中只能容纳10-20个这样的块)。由于ypu计划使用如此数量的内存,您需要仔细预算内存使用量,即整个缓冲区的简单复制将花费大量时间

当您完成特定的块时,您可以自己强制GC。听起来GC.Collect API的使用很合理——您已经使用了所有可用内存的很大一部分


你也可以考虑转换较小的(64K)块,并将它们链接在一起,如果它适用于你的应用程序。这将更好地与垃圾收集保持一致,并可能为您的应用程序提供更大的灵活性。

据我所知,垃圾收集器中大于75k的文件被视为不可移动的,它们不属于三代文件中的任何一代。我倾向于不同意大对象堆(LOH)。引入LOH的目的是降低垃圾收集大型对象的成本。与标准托管堆相比,LOH还应用了其他规则,即GC不会压缩LOH中的内存,因此使用大型对象不会带来巨大的损失。我认为约翰·斯基特或埃里克·利珀特或其他人会更好地解释这件事。Jeffrey Richer在他的CLR via C#中有一整章专门讨论托管堆。虽然它们不是一代堆的直接部分,但它们是一代堆的一部分,因为它们是由该代的GC运行收集的。从我读到的(可能已经过时)LOH只在Gen2系列上收集。我有一些代码分配了大约10个每秒几MB的对象,但效果不好。一旦我引入了游泳池,问题就消失了。仅仅使用大型对象不会受到惩罚,但是持续分配它们会受到很大的惩罚。