文章

Resources.UnloadUnusedAssets 需要注意错峰执行

场景objects数量在Loading进战场时达到118060,此时触发UnloadUnusedAssets,引擎通过FindAllLiveObjects收集所有Object,并为其建立ObjectState结构,每个ObjectState 20个字节,20*118060=2.25M

其后调用CreateObjectToIndexMappingFromNonRootObjects并分配 2倍的内存的Dictionary空间(2*2.25M=4.5M),把FindAllLiveObjects的ObjectState插入临时变量里以供后面使用

所以UnloadUnusedAssets时产生了约6.75M内存

1
2
3
4
5
6
7
8
struct ObjectState
{
    Object* object;
    RuntimeTypeIndex typeIndex : 29;
    UInt32  marked        : 1;
    UInt32  isPersistent  : 1;
    UInt32  dontUnload      : 1;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#if ASSET_REMAP_TABLE
static void CreateObjectToIndexMappingFromNonRootObjects(GarbageCollectorState& gcState)
{
    PROFILER_AUTO(gGCBuildLiveObjectMaps, NULL);

    gcState.instanceIDToIndex.set_empty_key(-1);
    gcState.instanceIDToIndex.set_deleted_key(-2);

    SInt32 largestInstanceID = 0;

    for (size_t i = 0; i < gcState.liveObjects.size(); ++i)
    {
        ObjectState& state = gcState.liveObjects[i];
        if (state.marked == 0)
        {
            int instanceID = state.object->GetInstanceID();

            if (instanceID > 0)
            {
                largestInstanceID = std::max<SInt32>(largestInstanceID, instanceID);
            }
            else
            {
                gcState.instanceIDToIndex.insert(std::make_pair(instanceID, i));
            }
        }
    }

    // Cap the memory of dense assetRemapTable
    if (largestInstanceID < (kMaximumAssetRemapTableSize / sizeof(UInt32)))
    {
        gcState.assetRemapTable.resize_initialized(largestInstanceID + 1, -1);
        for (size_t i = 0; i < gcState.liveObjects.size(); ++i)
        {
            ObjectState& state = gcState.liveObjects[i];
            if (state.marked == 0)
            {
                int instanceID = state.object->GetInstanceID();

                if (instanceID > 0)
                    gcState.assetRemapTable[instanceID] = i;
            }
        }
    }
    // Use hashtable for all instance ids as a fallback
    else
    {
        for (size_t i = 0; i < gcState.liveObjects.size(); ++i)
        {
            ObjectState& state = gcState.liveObjects[i];
            if (state.marked == 0)
            {
                int instanceID = state.object->GetInstanceID();

                if (instanceID > 0)
                    gcState.instanceIDToIndex.insert(std::make_pair(instanceID, i));
            }
        }
    }
}

#else
static void CreateObjectToIndexMappingFromNonRootObjects(GarbageCollectorState& gcState)
{
    gcState.instanceIDToIndex.reserve(gcState.liveObjects.size() * 2);

    for (int i = 0; i < gcState.liveObjects.size(); ++i)
    {
        ObjectState& state = gcState.liveObjects[i];
        if (state.marked == 0)
        {
            InstanceID instanceID = state.object->GetInstanceID();

            gcState.instanceIDToIndex.insert(instanceID, i);
        }
    }
}

#endif
本文由作者按照 CC BY 4.0 进行授权