Unity il2cpp new 内存分配过程

Unity il2cpp new 内存分配过程

Unity版本:Unity 2020.1.0f1
使用工具:Unity工程文件,IDA pro,X32dbg(这里都使用32位工程)

过程

源代码为

public class ClassNew{
public int a = 1;
public int b = 2;
public int c = 3;
}
classNew = new ClassNew();

il2cpp编译成的C++代码为

		// classNew = new ClassNew();
		ClassNew_t1698357DCBE408EC7AD7C866F038F723340D270E * L_16 = (ClassNew_t1698357DCBE408EC7AD7C866F038F723340D270E *)il2cpp_codegen_object_new(ClassNew_t1698357DCBE408EC7AD7C866F038F723340D270E_il2cpp_TypeInfo_var);
		ClassNew__ctor_m6D3C0D4DD6A25602EBB11B3F5FC5268FD0CA2C40(L_16, /*hidden argument*/NULL);

这里就需要去寻找il2cpp_codegen_object_new这个函数

    RuntimeObject* il2cpp_codegen_object_new(RuntimeClass *klass)
    {
        return il2cpp::vm::Object::New(klass);
    }
    Il2CppObject* Object::New(Il2CppClass *klass)
    {
        // same as NewAllocSpecific as we only support a single domain
        return NewAllocSpecific(klass);
    }
    //再往下
    Allocate(klass->instance_size, klass);
    //之后可以看到
//如果分配内存小于等于7FFh就可以直接从ok_freelist直接分配这里更GC_generic_malloc_inner中的情况差不多(可以参考我另一篇贝姆垃圾回收的文章)
    GC_malloc_kind_global(size_t lb, int k)
    //如果没有符合的内存块还是会调用GC_generic_malloc_inner进行分配
    GC_INNER void * GC_generic_malloc_inner(size_t lb, int k)
    
    

现在就来看看实例化classNew之后,贝姆回收器,会分配多少内存:

用x96dbg运行测试程序,断点打再new地方.

05955F30 | E8 9B320100         | call <gameassembly._GC_malloc_atomic>                                                           
//然后是GC_malloc_kind(lb, PTRFREE);
//发现lb是0x14有20个字节 GC_size_map[0x14] 为3,所以一共会分配24字节得块
//再去看ok_freelist是否有空闲得,可以看到一堆为24字节得块
0283C108  0283C0F0  
0283C10C  00000000  
0283C110  00000000  
0283C114  00000000  
0283C118  00000000  
0283C11C  00000000  
0283C120  0283C108  
0283C124  00000000  
0283C128  00000000  
0283C12C  00000000  
0283C130  00000000  
0283C134  00000000  
0283C138  05824DC8  
0283C13C  00000000  
0283C140  00000000  
//最后等赋值完毕
0283C114  00000000  
0283C118  00000000  
0283C11C  00000000  
0283C120  0E8D78F8  
0283C124  00000000  
0283C128  00000001  
0283C12C  00000002  
0283C130  00000003  
0283C134  00000000  
0283C138  05824DC8  
0283C13C  00000000  
0283C140  00000000  
0283C144  00000000  
0283C148  00000000  
0283C14C  00000000  
//证实了Unity BoemhGC 的分配方式

问题

问:ClassNew明明只占12个字节为啥,要0x14(20)个字节?

答:因为ClassNew在il2cpp中继承于Il2CppObject

typedef struct Il2CppObject
{
    union
    {
        Il2CppClass *klass;//class类型数据
        Il2CppVTable *vtable;//虚表数据
    };
    MonitorData *monitor;//监视数据
} Il2CppObject;

问:贝姆是如何决定分配内存时在freeptr还是在normal里的?

答:首先klass->has_references判断类中是否有引用

        if (!klass->has_references)
        {
            o = NewPtrFree(klass);
        }
#if IL2CPP_HAS_GC_DESCRIPTORS
        else if (klass->gc_desc != GC_NO_DESCRIPTOR)
        {
            o = AllocateSpec(klass->instance_size, klass);
        }
#endif
        else
        {
            o = Allocate(klass->instance_size, klass);
        }

其次看klass的来源,这里是由il2cpp_codegen_object_new(ClassNew_t1698357DCBE408EC7AD7C866F038F723340D270E_il2cpp_TypeInfo_var);传入ClassNew_t1698357DCBE408EC7AD7C866F038F723340D270E_il2cpp_TypeInfo_var这个值,被g_MetadataUsages列表所引用.列表会用global-metadata.dat初始化.

所以元数据global-metadata.dat的TypeInfo决定了,贝姆要分配什么样的内存,来龙去脉就是这样.

建议

1.创建class时,颗粒度要注意,32位和64位都会有8字节和16字节额外字节.

2.简单的数据结构就少加入引用,方便GC收集的删除.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值