기술적으로 당신은 바 런타임과 unsafe.Pointer
을 사용하여 메모리를 할당 할 수 있습니다. 그러나 이것은 틀린 일입니다.
더 나은 솔루션은 할당 횟수를 줄이는 것입니다. 버퍼를 루프 바깥으로 이동하거나 goroutine 버퍼가 필요한 경우 풀에 여러 버퍼를 할당하고 필요할 때마다 할당하십시오.
type BufferPool struct {
Capacity int
buffersize int
buffers []byte
lock sync.Mutex
}
func NewBufferPool(buffersize int, cap int) {
ret := new(BufferPool)
ret.Capacity = cap
ret.buffersize = buffersize
return ret
}
func (b *BufferPool) Alloc() []byte {
b.lock.Lock()
defer b.lock.Unlock()
if len(b.buffers) == 0 {
return make([]byte, b.buffersize)
} else {
ret := b.buffers[len(b.buffers) - 1]
b.buffers = b.buffers[0:len(b.buffers) - 1]
return ret
}
}
func (b *BufferPool) Free(buf []byte) {
if len(buf) != b.buffersize {
panic("illegal free")
}
b.lock.Lock()
defer b.lock.Unlock()
if len(b.buffers) < b.Capacity {
b.buffers = append(b.buffers, buf)
}
}
또한이 예에서 버퍼에서 Free를 호출하는 것을 잊어 버리면 가비지 수집이되고 풀에 다시 추가되지 않고 누출되지 않습니다. – cthom06
해제 된 버퍼를 저장하기 위해 버퍼링 된 채널을 사용해야합니까? –
@MattJoiner 대신 그렇게 할 수는 있지만 버퍼링 된 아이템 수를 안전하게 확인하려면 잠금 장치가 필요합니다. 그러면 두 번 잠그거나 길이를 확인하지 않고 goroutines이 누출 될 것입니다. 항상 (peak_use - 수용량) goroutines가 채널을 밀기를 기다리고 있습니다. – cthom06