public object Allocate()
        {
            Interlocked.Increment(ref AllocCount);

#if (NET_2_0)
            Core.Utils.SpinWait spin = new Core.Utils.SpinWait();
#else
            System.Threading.SpinWait spin = new System.Threading.SpinWait();
#endif
            while (Interlocked.Increment(ref _allocatorNumber) != 1)
            {
                Interlocked.Decrement(ref _allocatorNumber);
                spin.SpinOnce();
            }
            object obj;
            var    succ = _pool.TryDequeue(out obj);
            Interlocked.Decrement(ref _allocatorNumber);
            if (!succ || obj == null)
            {
                Interlocked.Increment(ref NewCount);
                obj = _factory.MakeObject();
            }

            _factory.ActivateObject(obj);
            return(obj);
        }
        // there may be some leak while increasing cap
        // but it's ok...
        public void Free(object t)
        {
            if (t == null)
            {
                return;
            }


            _factory.DestroyObject(t);
            Interlocked.Increment(ref FreeCount);
#if (NET_4_6 && UNITY_2017)
            System.Threading.SpinWait spin = new System.Threading.SpinWait();
#else
            Core.Utils.SpinWait spin = new Core.Utils.SpinWait();
#endif
            while (Interlocked.Increment(ref _freeNumber) != 1)
            {
                Interlocked.Decrement(ref _freeNumber);
                spin.SpinOnce();
            }
            if (_pool.Count > _pool.Capacity - 5)
            {
                _old  = _pool;
                _pool = new RingBuffer <object>(_old.Capacity * 2);
                _logger.InfoFormat("ring buffer not big enough for object pool of type {0}",
                                   _factory.MakeObject().GetType());
                if (_old.Count > 0)
                {
                    object obj;
                    var    succ = _old.TryDequeue(out obj);
                    while (succ && obj != null)
                    {
                        _pool.Enqueue(obj);
                        succ = _old.TryDequeue(out obj);
                    }
                }
                _old = null;
            }



            {
                _pool.Enqueue(t);
                Interlocked.Decrement(ref _freeNumber);
            }
        }