.net BufferManager的真实用例

.net BufferManager的真实用例,.net,buffer-manager,.net,Buffer Manager,试图找出OutOfMemoryException的根源,我发现WCF的buffered TransferMode使用的.net造成了数百兆字节的浪费(有关详细信息,请参阅问题和我自己的答案,以及如何通过简单地从“buffered”(缓冲)切换到“streamed”(流式)来修复它) 撇开WCF不谈,BufferManager是作为一种性能更好的替代品而发明的,它可以替代您通常所做的工作:只需在需要字节数组时分配它们,并在引用超出范围时依靠GC清理和回收它们 所以我的问题是:有没有人在现实世界的应

试图找出OutOfMemoryException的根源,我发现WCF的buffered TransferMode使用的.net造成了数百兆字节的浪费(有关详细信息,请参阅问题和我自己的答案,以及如何通过简单地从“buffered”(缓冲)切换到“streamed”(流式)来修复它)

撇开WCF不谈,BufferManager是作为一种性能更好的替代品而发明的,它可以替代您通常所做的工作:只需在需要字节数组时分配它们,并在引用超出范围时依靠GC清理和回收它们

所以我的问题是:有没有人在现实世界的应用程序中使用过BufferManager,从而在性能方面产生了显著的差异,从而证明手动操作带来的不便。清除()BufferManager(如果有必要的话)


如果是这样的话,仅仅手动创建一个单字节缓冲区并保留对它的引用并不能解决这个问题吗?

我最近在一个代理服务上工作,该服务接受多个客户端连接(最多500个同时连接)。代理将客户端请求中继到目标服务器,并将响应从目标服务器中继回客户端。代理服务使用字节数组(字节[])作为缓冲区来发送和接收数据。我没有缓冲区管理器

代理每次都创建一个新的字节数组,以从套接字发送和接收数据。资源监视器中的专用字节不断增加。运行AntMemoryProfiler工具时,显示了不断增加的大片段

解决方案是实现一个简单的Buffermanager类来管理缓冲区使用的内存。下面是代码片段

public class BufferManager
    {
        private readonly int m_ByteSize;

        private readonly Stack<byte[]> m_Buffers;
        private readonly object m_LockObject = new Object();

        #region constructors

        public BufferManager(int _byteSize, int _poolCount)
        {
            lock (m_LockObject)
            {
                m_ByteSize = _byteSize;
                m_Buffers = new Stack<Byte[]>(_poolCount);  
                for (int i = 0; i < _poolCount; i++)
                {
                    CreateNewSegment();
                }
            }
        }

        #endregion //constructors

        public int AvailableBuffers
        {
            get { return m_Buffers.Count; }
        }


        public System.Int64 TotalBufferSizeInBytes
        {
            get { return m_Buffers.Count * m_ByteSize; }
        }

        public System.Int64 TotalBufferSizeInKBs
        {
            get { return (m_Buffers.Count * m_ByteSize/1000); }
        }

        public System.Int64 TotalBufferSizeInMBs
        {
            get { return (m_Buffers.Count * m_ByteSize/1000000); }
        }



        private void CreateNewSegment()
        {
            byte[] bytes = new byte[m_ByteSize];
            m_Buffers.Push(bytes);
        }



        /// <summary>
        /// Checks out a buffer from the manager
        /// </summary>        
        public Byte[] CheckOut()
        {
            lock (m_LockObject)
            {
                if (m_Buffers.Count == 0)
                {
                    CreateNewSegment();

                }
                return m_Buffers.Pop();
            }
        }


        /// <summary>
        /// Returns a buffer to the control of the manager
        /// </summary>
        ///<remarks>
        /// It is the client’s responsibility to return the buffer to the manger by
        /// calling Checkin on the buffer
        ///</remarks>
        public void CheckIn(Byte[] _Buffer)
        {
            lock (m_LockObject)
            {
                m_Buffers.Push(_Buffer);
            }
        }


    }
公共类缓冲区管理器
{
私有只读int m_字节大小;
专用只读堆栈m_缓冲区;
私有只读对象m_LockObject=新对象();
#区域构造函数
公共缓冲区管理器(int\u字节大小,int\u池计数)
{
锁(m_锁对象)
{
m_ByteSize=_ByteSize;
m_Buffers=新堆栈(_poolCount);
对于(int i=0;i<\u poolCount;i++)
{
CreateNewSegment();
}
}
}
#endregion//构造函数
公共int可用缓冲区
{
获取{return m_Buffers.Count;}
}
public System.Int64 TotalBufferSizeInBytes
{
获取{return m_Buffers.Count*m_ByteSize;}
}
public System.Int64 TotalBufferSizeInKBs
{
获取{return(m_Buffers.Count*m_ByteSize/1000);}
}
public System.Int64 TotalBufferSizeInMBs
{
获取{return(m_Buffers.Count*m_ByteSize/1000000);}
}
私有void CreateNewSegment()
{
字节[]字节=新字节[m_字节大小];
m_Buffers.Push(字节);
}
/// 
///从管理器中签出缓冲区
///         
公共字节[]签出()
{
锁(m_锁对象)
{
如果(m_Buffers.Count==0)
{
CreateNewSegment();
}
返回m_Buffers.Pop();
}
}
/// 
///将缓冲区返回给管理器的控件
/// 
///
///客户有责任通过以下方式将缓冲区返回给经理:
///在缓冲区上调用Checkin
///
公共无效签入(字节[]_缓冲区)
{
锁(m_锁对象)
{
m_Buffers.Push(_Buffer);
}
}
}

我编辑了我的问题,以便(甚至)更清楚地表明我所说的是[.net的]()。我不知道您为什么要编写自己的一个(并用它来回答我关于.net实现的问题)。但是,不管怎样,除了您的实现从未释放一次获得的内存这一事实之外,您是否分析了将任务留给内置GC的情况?