简易内存管理 Arena

使用内存管理的好处

在cpp中,我们随意的申请使用空间,就会导致频繁使用系统调用,指针乱飞,内存空间不连续的问题
在go中,虽然go帮我们处理了系统调用的问题,但是依然会导致内存空间不连续
在ram中,连续的内存空间可以提高内存的访问效率

Arena

内存管理的思想是提前申请一块内存,根据我们的程序进行内存的分配,将连续的部分放到一块,提高程序执行效率

一些定义

考虑到 Arena 要配合 KV 引擎食用,在 KV 中我们只加不删,这样就可以让内存池只加不删
在 KV 引擎中数据积攒到一定程度就会持久化成sst文件,使整个 Arena 的内存会得到释放
释放整块内存借用 go 语言的内存管理即可

type Arena struct {
	offset uint32 //偏移地址(当前已经存储的数据量)
	buf    []byte //存储地址
}

如果我们知道一段数据在 buf 中的地址,和这段数据的长度,就可以从 Arena 中读取到这段数据

初始化

offset 指向第一块没被使用过的内存

func newArena(n int64) *Arena {
	out := &Arena{
		offset: 0,
		buf:    make([]byte, n),
	}
	return out
}

申请内存

输入需要申请的内存大小,返回申请完内存后的偏移地址
考虑到我们不能一开始就将内存池中的内存开到非常大,那么我们可以借用 c p p cpp cppvector 的思想,动态的扩张内存,当达到内存上界时使其翻倍,这样对于一个申请到一段长度为 n n n 的内存的过程,其时间和空间复杂度都是 O ( n ) O(n) O(n)

const MaxNodeSize int = 1 << 26 //64MB

func (s *Arena) allocate(n uint32) uint32 { //返回偏移地址
	offset := atomic.AddUint32(&s.offset, n)
	lenth := len(s.buf)
	if lenth-int(offset) < MaxNodeSize { //空间不足翻倍
		grow := lenth
		if grow > (1 << 30) {
			grow = 1 << 30
		}
		if uint32(grow) < n { // 防止一次扩展不够
			grow = int(n)
		}
		newBuf := make([]byte, lenth+grow)
		copy(newBuf, s.buf)
		s.buf = newBuf
	}
	return offset - n
}

接口与内存对齐

对于 64位/32位 的机器,我们让一段数据占用其基本数据大小的整数倍,可以提高内存访问效率,优化程序性能,并有利于数据并行处理。在大型软件和需要高性能计算的应用中,内存对齐可以带来明显的性能提升。

比如我们将一个跳表节点存入内存中,除了要考虑其 level 指针能否存满,还要对其内存进行对齐,那么我们就可以将这两个操作写成一个接口

const MaxHeight int = 30

func (s *Arena) putNode(height int) uint32 {
	nodeSize := uint32(unsafe.Sizeof(node{})) //这里我们暂定node会取得跳表跳至最高点使用的内存大小
	baseSize := uint32(unsafe.Sizeof(uint32(0))) //取得32/64位机器的基本数据大小
	unusedSize := uint32(MaxHeight-height) * baseSize
	sz := nodeSize - unusedSize
	sz += baseSize - sz%baseSize - 1 //内存对齐
	n := s.allocate(sz)
	return n
}

重新编码

在 kv 引擎中, v a l u e value value 的值可能有很多,我们可以将其编码成二进制文件,再写进 Arena
编码方式非常简单,具体代码将在整体实现放出

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值