一般来说,内存池都是采用预分配的方式,分为固定大小的和非固定大小块,固定大小的内存效率高,非固定大小灵活。同时,分为单线程和多线程版的,单线程不需要考虑并发问题。 
一般内存池的实现思想:分配一块比较大多内存,把这块内存分成大小相等的块,即固定大小,第一块要保存必要的信息,比如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()
}
 

golang 内存池的更多相关文章

  1. Golang内存管理

    Golang 内存管理 原文链接[http://legendtkl.com/2017/04/02/golang-alloc/] Golang 的内存管理基于 tcmalloc,可以说起点挺高的.但是 ...

  2. 图解golang内存分配机制 (转)

    一般程序的内存分配 在讲Golang的内存分配之前,让我们先来看看一般程序的内存分布情况: 以上是程序内存的逻辑分类情况. 我们再来看看一般程序的内存的真实(真实逻辑)图: Go的内存分配核心思想 G ...

  3. 基于C/S架构的3D对战网络游戏C++框架 _05搭建系统开发环境与Boost智能指针、内存池初步了解

    本系列博客主要是以对战游戏为背景介绍3D对战网络游戏常用的开发技术以及C++高级编程技巧,有了这些知识,就可以开发出中小型游戏项目或3D工业仿真项目. 笔者将分为以下三个部分向大家介绍(每日更新): ...

  4. berkeley db 内存池分配机制

    __memp_alloc() 注: MPOOL_ALLOC_SEARCH_DYN 没有 出现在 bdb document上, 也没出现在 除了mp_alloc外的代码里. 先删了 以便代码清楚. 按 ...

  5. golang内存分配

    golang内存分配 new一个对象的时候,入口函数是malloc.go中的newobject函数 func newobject(typ *_type) unsafe.Pointer { flags ...

  6. NGINX 内存池有感

    写在前面 写NGINX系列的随笔,一来总结学到的东西,二来记录下疑惑的地方,在接下来的学习过程中去解决疑惑. 也希望同样对NGINX感兴趣的朋友能够解答我的疑惑,或者共同探讨研究. 整个NGINX系列 ...

  7. 【uTenux实验】内存池管理(固定内存池和可变内存池)

    1.固定内存池管理实验 内存管理是操作系统的一个基础功能.uTenux的内存池管理函数提供了基于软件的内存池管理和内存块分配管理.uTenux的内存池有固定大小的内存池和大小可变的内存池之分,它们被看 ...

  8. boost的线程池和内存池 智能指针

    内存池为boost自带的 #include <boost/pool/pool.hpp> 或者另外一个开源的库: nedmalloc 一个高效率的库 线程池需要下载另外一个开源库 http: ...

  9. 对象池与.net—从一个内存池实现说起

    本来想写篇关于System.Collections.Immutable中提供的ImmutableList里一些实现细节来着,结果一时想不起来源码在哪里--为什么会变成这样呢--第一次有了想写分析的源码 ...

随机推荐

  1. luogu 1258 小车问题 小学奥数(?)

    题目链接 题意 甲.乙两人同时从A地出发要尽快同时赶到B地.出发时A地有一辆小车,可是这辆小车除了驾驶员外只能带一人.已知甲.乙两人的步行速度一样,且小于车的速度.问:怎样利用小车才能使两人尽快同时到 ...

  2. mybatis 判断参数有没有传入

    <!--审核展示列表--> <select id="auditResList" resultType="java.util.HashMap"& ...

  3. 解决Spring在线程中注入为空指针的问题

    在启用线程中使用来jdbcTemplate来查询数据库,引入jdbcTemplate是用Spring  @Autowired注解  方式引入,但是在运行中 jdbcTemplate 总是 空指针 解决 ...

  4. LeetCode OJ-- LRU Cache ***@

    https://oj.leetcode.com/problems/lru-cache/ 涨姿势的一道题,相当于实现一种数据结构,实现最近最少使用数据结构. // 用来记录 前后节点都是什么 类似链表上 ...

  5. nodejs Centos环境搭建

    使用二进制文件安装: node 环境下载 https://nodejs.org/en/download/ 下载里面的windows 安装包 和 linux 安装包 1)windows安装 window ...

  6. Linux centos 时间不同步 date 和 hwclock 时间不一致

    Linux centos 时间不同步 date 和 hwclock 网站有两台服务器,date 查看差3分钟 在应用 APP倒计时 与 直播,时时性较强的功能应用中 请求服务器后返回的服务器时间与数据 ...

  7. HDU 6249 Alice’s Stamps(2017 CCPC-Final G题,DP)

    题目链接 HDU 6249 题意 给定$m$个区间,在这些区间中选出不超过$k$个,求被覆盖的点的数量的最大值. 设$f[i][j]$表示选到第$i$个点并选了$j$个区间的时候能得到的最大答案. 处 ...

  8. [TJOI2014] 上升子序列

    刚刚做的时候一看:这不是个傻逼题吗hhhhh....然后发现写完了过不了样例,仔细一看题:同构的算一种. 这可咋办啊? 其实很简单,设f[i] 为 以a[i] 结尾的上升子序列个数,我们考虑当前如果算 ...

  9. 搭建 Maven ---基础入门

    这篇随笔从最基础的控制台  搭建maven讲,后面再升入的讲解IDEA搭建Maven. 一,Maven是什么?作用是什么? Maven是一个项目管理工具,它包含了一个项目对象模型 (Project O ...

  10. centos7.3 开放端口 防火墙端口

    1. 查看已打开的端口 # netstat -anp 2. 查看想开的端口是否已开 # firewall-cmd --query-port=666/tcp 若此提示 FirewallD is not ...