内存池管理思想 另类内存池实现
一般来说,内存池都是采用预分配的方式,分为固定大小的和非固定大小块,固定大小的内存效率高,非固定大小灵活。同时,分为单线程和多线程版的,单线程不需要考虑并发问题。 type bys_i struct { E *list.Element T int64 }
type ByteSlice struct { P *BytePool size_ int ls_ *list.List ls_m_ map[interface{}]*bys_i
ls_l sync.RWMutex
zero_ *list.Element
}
type BytePool struct { // Max int64 T int64 //timeout when gc Beg int End int ms_ map[int]*ByteSlice ms_l sync.RWMutex }
按照块的大小来维护,比如map[8]*ByteSlice,map[1024]*ByteSlice,同时,用list来做垃圾回收处理,对每个元素都设置访问时间T,若是GC时,T(当前)-T(元素)>T(GC条件),从map中delete并从list中remove。这原理跟session很相似,都是用map来存储,用list来做垃圾回收,因为map读取速度快,而list插入等操作比较灵活。 func NewByteSlice(p *BytePool,size int) *ByteSlice {
ls_ := list.New()
zero_ := ls_.PushBack([]byte{})
return &ByteSlice{
P: p,size_: size,ls_: ls_,zero_: zero_,ls_m_: map[interface{}]*bys_i{},}
}
func (b *ByteSlice) Alloc() []byte {
b.ls_l.Lock()
defer b.ls_l.Unlock()
var bys []byte
tv := b.ls_.Front()
if tv == b.zero_ {
bys = make([]byte,b.size_)
//add
count++
fmt.Printf("tv==b.zero_:%v,count:%dn",&bys[0],count)
//end
tv = b.ls_.PushBack(bys)
b.ls_m_[&bys[0]] = &bys_i{
E: tv,T: util.Now(),}
} else {
b.ls_.MoveToBack(tv)
bys = tv.Value.([]byte)
b.ls_m_[&bys[0]].T = util.Now()
fmt.Printf("moveToBack:%v,%d,util.Now(),count)
}
return bys
}
func (b *ByteSlice) Free(bys []byte) {
b.ls_l.Lock()
defer b.ls_l.Unlock()
if tv,ok := b.ls_m_[&bys[0]]; ok {
tv.T = util.Now()
b.ls_.MoveToFront(tv.E)
}
}
func (b *ByteSlice) Size() int64 {
// b.ls_l.Lock()
// defer b.ls_l.Unlock()
return int64(b.ls_.Len()-1) * int64(b.size_)
}
func (b *ByteSlice) GC() (int,int64) {
b.ls_l.Lock()
defer b.ls_l.Unlock()
tn := util.Now()
var rc int = 0
for {
tv := b.ls_.Front()
if tv == b.zero_ {
fmt.Printf("gc tv==b.zero_n")
break
}
bys := tv.Value.([]byte)
rv := &bys[0]
if (tn - b.ls_m_[rv].T) > b.P.T {
fmt.Printf("gc:%vn",rv)
b.ls_.Remove(tv)
delete(b.ls_m_,rv)
rc++
}
}
return rc,b.Size()
}
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |