15年前,当我使用Pascal编程时,我明白了为什么要使用两个人的能力来分配内存。但这似乎仍然是最先进的。
C#示例:
new StringBuilder(256);
new byte[1024];
int bufferSize = 1 << 12;我还是看到了几千次,我自己也用过这个,我还在质疑:
我们在现代编程语言和现代硬件中需要这一点吗?
我想这是很好的做法,但原因是什么呢?
编辑
例如,一个byte[]数组,正如这里的答案所述,2的幂是没有意义的:数组本身将使用16个字节(?),那么使用240 (=256-16)来容纳总共256个字节是否有意义?
发布于 2013-08-13 06:21:03
我们在现代编程语言和现代硬件中需要这一点吗?我想这是很好的做法,但原因是什么呢?
那得看情况。这里有两件事需要考虑:
假设您正在使用malloc()进行低级别的分配,那么使用页面大小的倍数将被认为是一个好主意,即4096或8192;这是因为它允许更有效的内存管理。
我的建议是只分配您需要的东西,让C#为您处理内存管理和分配。
发布于 2013-08-13 06:47:50
可悲的是,如果你想把一个内存块保存在一个4k的内存页中,那是相当愚蠢的。人们甚至不知道:-) (直到10分钟前我才知道.我只有一个预感)..。一个例子..。它是不安全的代码和实现依赖(使用.NET 4.5在32/64位)
byte[] arr = new byte[4096];
fixed (byte* p = arr)
{
    int size = ((int*)p)[IntPtr.Size == 4 ? -1 : -2];
}因此CLR至少分配了4096 + (1或2)大(Int).所以它已经超过了一个4k内存页。这是合乎逻辑的。它必须保持数组的大小,并且将它与数组放在一起是最明智的事情(对于那些知道Pascal和BSTR是什么的人来说,是的,这是相同的原则)
我要补充的是,.NET中的所有对象都有一个同步数字和一个RuntimeType.它们至少是int (如果不是IntPtr ),所以总共有8到16个字节/对象(这在不同的地方都有解释.如果你感兴趣的话,试着去找.net object header )
发布于 2013-08-13 06:32:48
在某些情况下,这仍然是有意义的,但我更愿意逐个分析我是否需要这种规范,而不是盲目地把它作为良好的实践。
例如,在某些情况下,您可能希望使用确切的8位信息(1字节)来寻址表。
在这种情况下,我会让表的大小为2^8。
Object table = new Object[256];这样,您就可以只使用一个byte来处理表中的任何对象。
即使该表实际上较小,并且没有使用所有256个位置,您仍然可以保证从表到索引和从索引到表之间的双向映射,这可以防止出现错误,例如,如果您有:
Object table = new Object[100];然后有人(可能是其他人)使用超出表范围的字节值访问它。
也许这种双射行为可能是好的,也许你可以有其他的方法来保证你的约束。
也许,鉴于当前编译器的智能性增加,这不再是唯一的好做法了。
https://stackoverflow.com/questions/18201761
复制相似问题