C#System.Buffer.BlockCopy内存问题?
我有一个困扰我几天的问题。我曾尝试用谷歌搜索这个问题,但迄今为止还没有找到任何解决方案,甚至没有一个人有同样的问题 似乎C#method System.Buffer.BlockCopy给您留下了某种内存重影。例如,我有以下方法:C#System.Buffer.BlockCopy内存问题?,c#,memory-leaks,garbage-collection,buffer,C#,Memory Leaks,Garbage Collection,Buffer,我有一个困扰我几天的问题。我曾尝试用谷歌搜索这个问题,但迄今为止还没有找到任何解决方案,甚至没有一个人有同样的问题 似乎C#method System.Buffer.BlockCopy给您留下了某种内存重影。例如,我有以下方法: private float[,] readFloatArray2 (byte[] b) { int floatSize = sizeof(float); float[,] v = new float[2, (b.Length / 2) / floatSize
private float[,] readFloatArray2 (byte[] b) {
int floatSize = sizeof(float);
float[,] v = new float[2, (b.Length / 2) / floatSize];
System.Buffer.BlockCopy(b, 0, v, 0, b.Length);
return v;
}
将字节数组转换为二维浮点数组。数据先前是从流中读取的。
我已确定问题出在System.Buffer.BlockCopy方法上
如果我删除BlockCopy命令,应用程序使用的内存将是大小的一半。这意味着字节数组仍然存在不是我的错。因为没有BlockCopy命令,字节数组将正常消亡。无论如何都会创建浮点数组(有或没有复制的信息) 我不确定这是BlockCopy命令还是GC的问题,因为我也尝试调用System.GC.Collect();在区块复制之后,它也可以完美地工作(我知道你不应该这样做……这就是我在这里寻求建议的原因) 我也不想费心问,但这个问题涉及几百兆 除了内存问题外,该方法工作得非常好。有人知道是什么导致了记忆问题吗 提前问候和感谢 奥利
ps:我正在使用.NET4.0与Visual Studio 2010 PRO和WIN7。。。不知道这是否相关。BlockCopy没有托管的.NET实现。在内部,它调用外部WinAPI
[SecuritySafeCritical]
public static extern void BlockCopy(Array src, int srcOffset, Array dst, int dstOffset, int count);
Buffer.BlockCopy
基于字节而不是基于索引。我建议您使用Array.Copy,它的作用基本相同。BlockCopy只是稍微快一点
首先需要将字节[]转换为浮点[]。请查看下面的说明
static float[] ConvertByteArrayToFloat(byte[] bytes)
{
if(bytes == null)
throw new ArgumentNullException("bytes");
if(bytes.Length % 4 != 0)
throw new ArgumentException
("bytes does not represent a sequence of floats");
return Enumerable.Range(0, bytes.Length / 4)
.Select(i => BitConverter.ToSingle(bytes, i * 4))
.ToArray();
}
我发现问题出在System.Buffer.BlockCopy
方法上。如果我删除BlockCopy
命令,应用程序使用的内存将是大小的一半。这意味着字节数组仍然存在不是我的错。因为没有BlockCopy
命令,字节数组将正常消亡
我不同意这个结论。我看到几个阶段:
BlockCopy
的影响
步骤2保留并提交虚拟内存。因此,在这一步中,提交大小会增加。但由于数组的内容从未写入,并且完全由00
字节组成,因此windows内存管理器不会为其分配任何物理内存。它只是注意到这些页面完全由00
s组成
浮点数组的物理内存仅在步骤3中分配。如果添加一个初始化数组中每个字段的循环,则会得到相同的效果
除了实际问题外,我还有一些设计建议:
- 您可以轻松编写只在单个通道上运行的代码
- 实体2D阵列索引速度较慢,因此通常也更快
GC.Collect()
在实际程序中是有意义的,这很可能是其中之一,因此如果这样做“效果很好”,那么我就不会太担心99.9%的代码会违反最佳实践。这是“最佳实践”而不是硬性规定的原因是,有时我们处于0.1%的情况下,通常的最佳实践不再是最佳实践
此外,如果您可以提前预测数组的最大大小(或者如果不能预测,仅源字节数组),那么CodeInChaos的第一种方法可能会奏效。使用10000000字节来处理32实际上并没有什么坏处,只要在某个时候您确实会使用10000000字节。重新使用10000000可以在流程的整个生命周期内实现真正的节约。ok。。。如何处理这个问题?你有什么建议?没什么。当它需要额外的内存时,GC最终会处理它。如果你说内存是由
GC.Collect
正确收集的,那么一切都很好b
最终将由普通GC在适当的时候收集。如果您正在处理音频数据,我将使用floa形式的锯齿数组