使用delegate时产生的GC

2回答

使用delegate时产生的GC

提问者 风歌四弦秋 2017-06-02 410浏览
public delegate void Del();
void Fun()
{

}
void TestDelegete()
{
    Del d = Fun;
}

这几行代码,在调用TestDelegete()时总会产生104B的GC,而由于各种原因这个方法是需要被调用很多次的。问下这个GC能够被减少或者避免么?

快来消灭0回答吧

{{ dataList.answer_count | view-format }}回答
  • 程序媛Adele 2017-06-05 10:08
    Mono 对象可以用GC,Unity的对象有自己的处理规则,不适用GC处理;
    话说实在是要停止或减少GC的话,可以尝试下面的办法:

    using UnityEngine;
    using System.Collections.Generic;
    using System;
    using System.Runtime.InteropServices;
     
    public class gc_manager : MonoBehaviour {
      
        [DllImport("kernel32.dll", CharSet=CharSet.Auto)]
        static extern IntPtr GetModuleHandle(string lpModuleName);
         
        [DllImport("kernel32.dll", CharSet=CharSet.Ansi, ExactSpelling=true, SetLastError=true)]
        static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
         
        static Action mono_gc_disable;
        static Action mono_gc_enable;
         
        static bool mono_gc_loaded=false;
         
        static bool load_mono_gc() {
            if (mono_gc_loaded) {
                return true;
            }
           
            unsafe {
                //extracted from mono.pdb using dbh.exe (using the "enum *!*mono_gc_*" command)
                //note: for the 64 bit editor, there is only a 64 bit version of mono.pdb, so you need to also download the 32 bit editor to update this for 32 bit standalone builds
                // (you also need to decide which version of the dll to use; this can be done by comparing the mono_gc_collect offset with the two offsets for the 32 bit and 64 bit dlls)
                int offset_mono_gc_disable=0x1b100;
                int offset_mono_gc_enable=0x1b108;
                int offset_mono_gc_collect=0x1b0b4; //this is used to verify that mono.dll hasn't changed
               
                IntPtr mono_module=GetModuleHandle("mono.dll");
                IntPtr func_ptr_mono_gc_collect=new IntPtr(mono_module.ToInt64()+offset_mono_gc_collect);
                IntPtr expected_func_ptr_mono_gc_collect=GetProcAddress(mono_module, "mono_gc_collect");
                if (func_ptr_mono_gc_collect!=expected_func_ptr_mono_gc_collect) {
                    //if you see this error, you need to update the "offset_mono_gc_" variables above
                    Debug.Log("Cannot load gc functions. Expected collect at "+ func_ptr_mono_gc_collect.ToInt64() +" Actual at "+ func_ptr_mono_gc_collect.ToInt64() +" Module root "+ mono_module.ToInt64());
                    return false;
                }
               
                mono_gc_enable=(Action)Marshal.GetDelegateForFunctionPointer(new IntPtr(mono_module.ToInt64()+offset_mono_gc_enable), typeof(Action));
                mono_gc_disable=(Action)Marshal.GetDelegateForFunctionPointer(new IntPtr(mono_module.ToInt64()+offset_mono_gc_disable), typeof(Action));
            }
           
            mono_gc_loaded=true;
            return true;
        }
     
    };

    0评论
  • 此年此景 2017-06-05 10:28
    其实可以这么简单的来做,用用List<Delegate>数据结构来实现
    public class EventDispather : MonoBehaviour {
        public delegate void EventHandler();
        public List<EventHandler> _handlers =new List<EventHandler>();
        void AddHandler(EventHandler handler){
            if (!_handlers.Contains (handler)) {
                _handlers.Add (handler);
            }
        }
        void RemoveHandler(EventHandler handler)
        {
            if (_handlers.Contains (handler)) {
                _handlers.Remove (handler);
            }
        }
        class Example{
            public  EventDispather dispatcher;
            EventHandler _Example_Handler;
            public Example()
            {
                dispatcher = new EventDispather();
                _Example_Handler = Example_Handler; //缓存函数代理的引用
            }
            public void Update()
            {
                //dispatcher.AddHandler (Example_Handler);//gc warning!!
                //dispatcher.RemoveHandler (Example_Handler);//gc warnning!!
                dispatcher.AddHandler (_Example_Handler);
                dispatcher.RemoveHandler (_Example_Handler);
            }
            public void Example_Handler()
            { }
            }
    }
    0评论
  • {{ answer.user.NickName }} {{ answer.profession }} {{ answer.created_at | time-format }}
    专家回答
    {{{ answer.answer }}}
    {{ answer.answer_count | view-format }}评论
加载中... 查看更多回答