zoukankan      html  css  js  c++  java
  • 【笔记】对golang的大量小对象的管理真的是无语了……

    业务中有这样一个struct:

    type bizData struct{
       A uint64
       B uint64
      C int32
      D uint32
    }
    

    虽然没有实测,但我猜测这样的对齐方式,这个struct占24字节。
    业务中用一个map指向这些对象: map[uint64]*bizData
    这样的存储对象,一个容器开启10GB内存,最多存储60万左右的对象,容器内存就爆了。

    于是自己实现一个简易的内存池:mempool.go

    package mempool
    
    //实现一个按块扩展的内存池
    
    type memPool struct {
    	datas        [][]bizData
    	freeNode     chan uint32
    	countOfBlock int
    }
    
    //NewMemPool 构造内存池对象
    func NewMemPool(countOfBlock int) *memPool {
    	out := &memPool{
    		datas:        [][]bizData{make([]bizData, countOfBlock)},
    		freeNode:     make(chan uint32, countOfBlock),
    		countOfBlock: countOfBlock,
    	}
    	for i := 0; i < countOfBlock; i++ {
    		out.freeNode <- uint32(i)
    	}
    	return out
    }
    
    func (pool *memPool) moreBlock() {
    	pool.datas = append(pool.datas, make([]bizData, pool.countOfBlock))
    	ch := make(chan uint32, len(pool.datas)*pool.countOfBlock)
    	close(pool.freeNode)
    	for item := range pool.freeNode {
    		ch <- item
    	}
    	start := (len(pool.datas) - 1) * pool.countOfBlock
    	for i := 0; i < pool.countOfBlock; i++ {
    		ch <- uint32(start + i)
    	}
    	pool.freeNode = ch
    }
    
    func (pool *memPool) Get() uint32 {
    	if len(pool.freeNode) == 0 {
    		pool.moreBlock()
    	}
    	select {
    	case idx := <-pool.freeNode:
    		return idx
    	default:
    		panic("impossible")
    	}
    }
    
    func (pool *memPool) Put(idx uint32) {
    	pool.freeNode <- idx
    }
    
    func (pool *memPool) Item(idx uint32) *bizData {
    	blockIdx := int(idx) / pool.countOfBlock
    	loc := int(idx) % pool.countOfBlock
    	return &(pool.datas[blockIdx][loc])
    }
    

    然后把对象的引用方式修改为: map[uint64]uint32 //值映射数据块的下标
    使用上面的内存池后,分配250万小对象,进程内存始终未超过600mb!!

    so, 大量小对象的情况下,自己实现内存池更好!

  • 相关阅读:
    正则表达式尽量写的精简,提高运行效率
    IndexError:string index out of range
    Python3 字符编码
    python3字符编码错误
    pip
    正则贪婪和非贪婪
    [Ss]+ 可以匹配多行html,最常用的还是.*?
    正则,分组,字符集,使用场景
    使用jodis连接codis的时候报异常:Exception in thread "main" redis.clients.jedis.exceptions.JedisException: Proxy list empty
    codis 的dashboard服务无法启动 提示pid已经运行
  • 原文地址:https://www.cnblogs.com/ahfuzhang/p/15256614.html
Copyright © 2011-2022 走看看