golang 記憶體池

來源:互聯網
上載者:User

一般來說,記憶體池都是採用預分配的方式,分為固定大小的和非固定大小塊,固定大小的記憶體效率高,非固定大小靈活。同時,分為單線程和多線程版的,單線程不需要考慮並發問題。 
一般記憶體池的實現思想:分配一塊比較大多記憶體,把這塊記憶體分成大小相等的塊,即固定大小,第一塊要儲存必要的資訊,比如nfirst(第一塊可分配到塊),nsize(共分配了多少),nfree(可分配塊大小),pnext(若是記憶體池不夠,分配一塊growth,pnext指向下一塊),p(儲存第一可分配記憶體塊的地址),同時還需要poolmanage來統一做管理。每一個記憶體塊的頭兩個位元組記錄下一個可分配的記憶體塊的地址,因為是固定大小的,所以可以根據p和第幾塊算出地址。頭兩個位元組分配的好處就是分配之後記憶體可複用,注意在歸還到記憶體池的時候頭兩個位元組也是需要記錄下一個可分配的記憶體塊地址。 
這就是記憶體池的思想,好了,其實今天的主題不是記憶體池,而是另外一種記憶體管理的方法,按照塊的大小來分配:

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插入等操作比較靈活。 
go代碼:

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:%d\n", &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,count:%d\n", &bys[0], 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:%v\n", rv)            b.ls_.Remove(tv)            delete(b.ls_m_, rv)            rc++        }    }    return rc, b.Size()} 


相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.