统一及;C#对象内存比预期大30%?!我怎样才能避免如此巨大的开销?

统一及;C#对象内存比预期大30%?!我怎样才能避免如此巨大的开销?,c#,.net,unity3d,C#,.net,Unity3d,好的,我正在Unity中开发一个应用程序,它高度依赖于内存。因此,我将数据存储为字节数组中的两个字节字。我还需要每4000个字左右就可以立即访问,无需复制数据就可以移动和修改,因此,我不使用单个大字节数组,而是保留一个简单对象数组,每个对象只包含一个8000字节数组(这些数据子单元的大小很重要,不能真正更改) 问题是:我希望每个对象的大小都小于9000字节(为NET framework的管理开销提供足够的空间)。然而,当我实际测试这些简单对象的大小时,它们每个大约消耗12000字节?!我理解内存

好的,我正在Unity中开发一个应用程序,它高度依赖于内存。因此,我将数据存储为字节数组中的两个字节字。我还需要每4000个字左右就可以立即访问,无需复制数据就可以移动和修改,因此,我不使用单个大字节数组,而是保留一个简单对象数组,每个对象只包含一个8000字节数组(这些数据子单元的大小很重要,不能真正更改)

问题是:我希望每个对象的大小都小于9000字节(为NET framework的管理开销提供足够的空间)。然而,当我实际测试这些简单对象的大小时,它们每个大约消耗12000字节?!我理解内存管理需要开销,但这30%的增长是不可接受的。我使用的任何数据结构的内存效率都非常重要,因为应用程序需要一次将多达20GB的数据加载到内存中。30%的开销意味着应用程序将无法在我的计算机上运行

那么,内存在哪里使用,有没有办法避免这么大的开销?恐怕我不太了解网络后端,不知道发生了什么。我已经查看了以下线程,但没有看到任何可以解释我所经历的开销量的内容:

虽然我认为可能是Unity造成了开销,但我不确定是否是这样,因为除了NUnit之外,我没有在这个特定功能上使用任何Unity库或模块进行测试

下面是我用来存储数据的示例类:

public class dataObject {
    public byte[] data;

    public dataObject() {
        this.data = new byte[8000];
    }
}
这是我用来测试内存中类大小的代码:

long mem1;
long mem2;
int N = 10000; // number of objects to create, a larger number gives a more accurate approximation of object size

mem1 = GC.GetTotalMemory(true);
dataObject[] dataObjectArray = new dataObject[N];
for (int i = 0; i < N; i++) {
    dataObjectArray[i] = new dataObject();
}
mem2 = GC.GetTotalMemory(true);

long dataObjectArraySize = (mem2 - mem1) / N;

认为C#与此有关是错误的。在统一C中,它只是一种“脚本”语言,因为它最终都会被转换成C++,然后编译成特定于平台的程序集。所以我认为大多数时候你对某些事情所能做的是非常有限的。特别是因为您将代码视为.NET,而实际上并非100%如此……而且,
GC.GetTotalMemory
在这种情况下并不是确定大小的正确方法。有各种各样的东西在统一中运行,它们分配内存,可能是并行的。在一个简单的.NET应用程序中,这很好,但是,正如前面所述,Unity不是.NET。您的
dataObjectArray
是一个引用数组,而不是一个实例数组;实例可以分布在整个堆中。结构数组更有意义,但它不一定能解决对齐问题。同样,您分配的数组是引用数组,而不是值数组。您的
byte[]data
成员本身就是一个引用。C#不是C。因此,您有一个对数据类型的引用数组,它本身包含对数组的引用,可以放在堆的任何位置,并以运行时(或内存管理器)认为合适的任何方式对齐。
GC.GetTotalMemory
不可能返回任何有意义的内容。不,这意味着您需要重新构造代码,并仔细考虑您正在使用的数据结构,以便对内存管理器更友好。目前,您的代码甚至无法度量您正在分配的数据量,更不用说开销了。启蒙在启动时运行,并分配各种资源,就像引擎中的其他进程一样。您正在测量GC负责的所有内容,而不仅仅是您的代码。
public struct dataStruct {
    public byte[] data;

    public dataStruct() {
        this.data = new byte[8000];
    }
}