关闭mono的GC,防止其带来的卡顿

我们的游戏品类特殊,对游戏对局内的画面流畅性要求极高。不允许出现可以明显察觉的卡顿。当我们解决了所有对象创建,JIT编译等带来的卡顿之后。还有一个较为棘手的卡顿来源就是GC。我们想了各种办法尽可能的减少对局内的内存分配。包括对UI的特殊处理,对网络消息的特殊处理。最后终于能够做到在一个对局之内不会产生GC。
但是,我们知道,这件事并不是一劳永逸的。随着关卡的继续开发,总有一天还会出现GC,有些内存分配是没办法彻底消除的,比如UI上变化的文字。因此我决定去搞mono本身。
首先是编译mono,这方面教程很多,比如【1】。然后就是设法开关GC,事实上mono内部有这样的功能函数,GC_enable和GC_disable,我们要做的不过是将这些符号导出。mono\mini\ldscript文件中描述了mono lib的导出符号,在其中增加GC_enable和GC_disable,重新编译,得到改造过的libmono.so。替换unity目录下的libmono(需要区分armv7和x86)
在C#中实现一个功能类,然后就可以愉快的开关GC功能了。

class GarbageCollection
{
#elif UNITY_ANDROID
    [DllImport("mono")]
    protected static extern void GC_enable();
    [DllImport("mono")]
    protected static extern void GC_disable();
#else
    protected static void GC_enable()
    {
    }
    protected static void GC_disable()
    {
    }
#endif
}

那么IOS平台呢,本来想使用跟android平台类似的方法。后来发现由于IOS上使用IL2CPP,mono被改造后集成进了libiPhone.a,同时大量符号都被导出了
包括GC_enable和GC_disable,也就是说在IOS上我们可以直接使用这两个接口,编译时不会遇到任何问题。
最后,我们的功能类就是这个样子

class GarbageCollection
{
    static bool enabled = true;
    public static bool Enable
    {
        get
        {
            return enabled;
        }
        set
        {
            if (value == enabled)
            {
                return;
            }
            if (value)
            {
                try
                {
                    GC_enable();
                }
                catch (System.Exception ex)
                {
                    Debug.Log("GC exception!");
                    Debug.Log(ex.ToString());
                }
            }
            else
            {
                try
                {
                    GC_disable();
                }
                catch (System.Exception ex)
                {
                    Debug.Log("GC exception!");
                    Debug.Log(ex.ToString());
                }
            }
            enabled = value;
        }
    }
#if UNITY_IPHONE
   
    [DllImport ("__Internal")]
    protected static extern void GC_enable();
    [DllImport ("__Internal")]
    protected static extern void GC_disable();

#elif UNITY_ANDROID
    [DllImport("mono")]
    protected static extern void GC_enable();
    [DllImport("mono")]
    protected static extern void GC_disable();

#else
    protected static void GC_enable()
    {
    }
    protected static void GC_disable()
    {
    }
#endif
}


做个简单的测试,在update里面不断的分配内存,很高兴的看到内存在飙涨。(这话怎么感觉怪怪的)





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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值