2011-11-26 80 views
1

我想优化一些代码,我有大量的数组包含不同大小的结构,但基于相同的接口。在某些情况下,结构体积较大,容纳的数据较多,而其他结构体系较小,而其他情况下,我希望保留空值作为节省内存的值。如何确定C#中的非托管数组的大小?

我的第一个问题是。做这样的事情是一个好主意吗?我以前有一个完整的数据结构数组,但是当测试混合它时,我几乎可以节省大量的内存。还有其他缺点吗?

我一直在尝试不同的事情,并且在制作一个通用接口数组时接缝工作得很好,但我不确定是否正确地检查了数组的大小。

为了简化这个例子不少。但是我在这里给数组添加了不同的结构。但我无法使用传统的Marshal.SizeOf方法来确定大小。简单地遍历集合并计算集合中每个值的sizeof是否正确?

IComparable[] myCollection = new IComparable[1000]; 
myCollection[0] = null; 
myCollection[1] = (int)1; 
myCollection[2] = "helloo world"; 
myCollection[3] = long.MaxValue; 

System.Runtime.InteropServices.Marshal.SizeOf(myCollection); 

最后一行将抛出此异常:

Type 'System.IComparable[]' cannot be marshaled as an unmanaged structure; no meaningful size or offset can be computed. 

借口长岗:

  1. 这是一个最佳的和可用的解决方案?
  2. 如何确定我的阵列的大小 ?
+0

我可能是错的,但它在我看来像你的IComparable []数组是一个托管数组? –

回答

0

最佳性总是取决于您的要求。如果你真的需要存储不同类/结构的许多元素,你的解决方案是完全可行的。

但是,我想你对数据结构的期望可能会误导:数组元素是每个定义都是相同的大小。在你的情况下甚至是这样的:你的数组本身并不存储元素,但引用(指针)。元素在VM堆的某处分配。所以你的数据结构实际上是这样的:它是一个1000个指针的数组,每个指针指向一些数据。每个特定元素的大小当然可以变化。

这会导致下一个问题:数组的大小。你打算怎么处理这个尺寸?当您将数据序列化到某些持久性存储时,是否需要知道要分配多少个字节?这取决于序列化格式......或者您需要粗略估计一下您的结构消耗了多少内存?在后一种情况下,您需要考虑数组本身以及每个特定元素的大小。您在示例中给出的数组大约消耗参考大小的1000倍(在32位计算机上应为4个字节,在64位计算机上应为8个字节)。要计算每个元素的大小,您确实可以遍历数组并总结特定元素的大小。请注意,这只是一个估计:虚拟机增加了一些内存管理开销,这是难以确定的确切...

+0

谢谢!这回答了我的问题。我主要想知道数组是如何保存在物理内存中的,因为我有很多数组,并且试图用较小的结构替换一些条目。根据你的说法,我可以从数组的大小*参考的内存使用情况+迭代时的数据内存大小来计算。正确? – jsmars

1

我可能是错的,但它在我看来像你的IComparable []数组是一个托管数组?如果是这样,那么你可以使用此代码来获取长度

int arrayLength = myCollection.Length; 

如果你正在做的C#和C之间的互操作平台++再回答你的问题的标题“我能找到一个非托管数组的长度”是否定的,这是不可能的。在C++/C数组函数签名倾向于遵循以下模式

void doSomeWorkOnArrayUnmanaged(int * myUnmanagedArray, int length) 
{ 
    // Do work ... 
} 

在.NET数组本身是具有一些基本信息,如它的大小,它的运行时类型等类型...因此,我们只要使用平台调用C#和C之间进行互操作可以使用此

void DoSomeWorkOnManagedArray(int [] myManagedArray) 
{ 
    int length = myManagedArray.Length; 
    // Do work ... 
} 

++你将需要数组的长度传递给接收功能,以及引脚阵列(但是这是一个不同的主题)。

这是回答您的问题吗?如果没有,那么请你澄清

+0

感谢您的回答,抱歉,如果问题不清楚。我主要想知道这样一个数组的内存使用情况。我有大量的数组保存大量数据,所以我试图用较小的优化结构替换一些条目,并且在某些情况下使用空值来节省物理内存。 – jsmars