비동기 소켓과 함께 사용할 간단한 버퍼 관리자 클래스를 만들었습니다. 이렇게하면 메모리 조각화를 방지하고 성능을 향상시킬 수 있습니다. 추가 개선 또는 다른 접근을위한 제안?스레드 안전 비 차단 버퍼 관리자에 대한 제안
public class BufferManager
{
private int[] free;
private byte[] buffer;
private readonly int blocksize;
public BufferManager(int count, int blocksize)
{
buffer = new byte[count * blocksize];
free = new int[count];
this.blocksize = blocksize;
for (int i = 0; i < count; i++)
free[i] = 1;
}
public void SetBuffer(SocketAsyncEventArgs args)
{
for (int i = 0; i < free.Length; i++)
{
if (1 == Interlocked.CompareExchange(ref free[i], 0, 1))
{
args.SetBuffer(buffer, i * blocksize, blocksize);
return;
}
}
args.SetBuffer(new byte[blocksize], 0, blocksize);
}
public void FreeBuffer(SocketAsyncEventArgs args)
{
int offset = args.Offset;
byte[] buff = args.Buffer;
args.SetBuffer(null, 0, 0);
if (buffer == buff)
free[offset/blocksize] = 1;
}
}
큰 제안! 먼저 메모리 조각화를 막기 위해 하나의 larg 버퍼를 사용하기로 결정했습니다. 그러나 모든 바이트가 동시에 할당되는시기는 중요하지 않을 수 있습니다. – remdao
단편화는 실제로 80K 이상인 버퍼의 경우에만 문제가됩니다. 단 80KB 이상의 할당이 압축을 얻지 않는 대형 오브젝트 힙에서 취해지기 때문입니다. GC가 콜렉션 후에 압축되어 조각화를 제거하는 정상적인 힙 (heap)은 더 적습니다. – AnthonyWJones
나는 버퍼 관리자를 바이트 배열의 스택으로 구현하는 것이 더 낫다는 것을 깨달았다.왜냐하면 오프셋을 추적 할 필요가 없다면 루프를 가질 이유가 없기 때문입니다. 바이트 배열 객체를 밀고 팝하는 것이 더 빠를 것입니다. – remdao