内存池的实现与场景分析

简介: 内存池的实现与场景分析

内存池场景分析

不同的场景下,内存池的设计是不一样的,以下是几个举例:

  1. 短链接和长连接。在kv存储中,经常以短链接为key,长链接为value。长链接的长度一般是固定的,短链接的长度一般也在某个区间内。我们在这种场景下只需要考虑固定分配的内存块。大块内存,不均匀内存等情况是不需要考虑的。
  2. 为每一个连接单独创建内存池。这种情况下内存池建立的时间和释放的时间和建立连接、断开连接的时点是一致的,内存块的大小根据业务场景的不同而定。
  3. 实现文章的存储。每篇文章的长短大小不一,需要的内存大小也不一。

我们设计内存池的不需要考虑得面面俱到,能把单一的场景解决得很好即可。比较通用且开源的内存池框架有jemalloc和tcmalloc等。

内存池的好处

  1. 避免了频繁的内存分配
  2. 避免了频繁分配内存导致的碎片化空隙。

针对固定块建立内存池

内存池包括管理用的结构体、内存页,以及内存页里被分割为多个小块。

设计内存池结构体

设计内存池结构体。内存池结构体的属性包括内存块大小、待使用的内存块的数量、下一个要使用的内存块的指针、内存页的指针。

设计内存池接口

包括初始化、销毁、分配、释放。

实现内存池的接口

内存页相关

首先,要先声明页的大小。

初始化内存池

先申请一块内存页。需要注意的是,内存页会被切割为多个内存块。每个内存块的前4个字节存放的是下一个内存块的地址,由此形成了一个单向链表便于后续管理。此处注意二级指针的用法,二级指针所指向的空间只能放置指针。

销毁内存池

直接销毁内存页即可

申请内存块

内存块是本身就存在的。申请内存块的本意是将下一个要使用的内存块的指针取出,取出完成后更新指针。

释放内存块

释放的时候,记得把被释放内存块里存储的指针指向释放前的空闲块,以便在利用该空闲块后,能接着使用本该使用的内存块。

运行结果

为每一个连接单独创建内存池

上一种内存池情况针对的情况是大小固定、释放时间不固定。这种情况是大小不固定,释放时间固定。当连接断开的时候,内存池也随之释放,所以只需要设计销毁函数不需要设计释放函数。其关键是将内存页串为链表,以及统一释放。

定义内存页节点和内存页链表管理结构体

内存页节点结构体包括:内存页剩余空间的起始地址,下一个内存页地址,刚好超出内存页末尾的地址。

内存页链表管理结构体包括:第一个内存页节点,当前使用的内存页节点,内存页的大小。

初始化内存页管理结构体

申请一个内存页,在内存页头部存放一个内存页结构体,用于形成管理对应的内存页,以及寻找下一个内存页。

同时修改内存页管理结构体。

销毁内存页节点

和正常地链表释放没有区别

申请内存使用

逻辑是如果在当前内存页可以申请到足够的内存空间直接申请。如果申请不到那么循环遍历之后的节点的空间是否足够。如果一直没有足够的空间,那么建立新的内存页节点。

运行结果

目录
相关文章
|
10天前
|
程序员 编译器 C++
【C++核心】C++内存分区模型分析
这篇文章详细解释了C++程序执行时内存的四个区域:代码区、全局区、栈区和堆区,以及如何在这些区域中分配和释放内存。
27 2
|
10天前
|
算法 程序员 Python
程序员必看!Python复杂度分析全攻略,让你的算法设计既快又省内存!
在编程领域,Python以简洁的语法和强大的库支持成为众多程序员的首选语言。然而,性能优化仍是挑战。本文将带你深入了解Python算法的复杂度分析,从时间与空间复杂度入手,分享四大最佳实践:选择合适算法、优化实现、利用Python特性减少空间消耗及定期评估调整,助你写出高效且节省内存的代码,轻松应对各种编程挑战。
22 1
|
12天前
|
存储 Prometheus NoSQL
Redis 内存突增时,如何定量分析其内存使用情况
【9月更文挑战第21天】当Redis内存突增时,可采用多种方法分析内存使用情况:1)使用`INFO memory`命令查看详细内存信息;2)借助`redis-cli --bigkeys`和RMA工具定位大键;3)利用Prometheus和Grafana监控内存变化;4)优化数据类型和存储结构;5)检查并调整内存碎片率。通过这些方法,可有效定位并解决内存问题,保障Redis稳定运行。
|
28天前
|
存储 运维
.NET开发必备技巧:使用Visual Studio分析.NET Dump,快速查找程序内存泄漏问题!
.NET开发必备技巧:使用Visual Studio分析.NET Dump,快速查找程序内存泄漏问题!
|
1月前
|
NoSQL 程序员 Linux
轻踩一下就崩溃吗——踩内存案例分析
踩内存问题分析成本较高,尤其是低概率问题困难更大。本文详细分析并还原了两个由于动态库全局符号介入机制(it's a feature, not a bug)触发的踩内存案例。
|
2月前
|
Python
Python变量的作用域_参数类型_传递过程内存分析
理解Python中的变量作用域、参数类型和参数传递过程,对于编写高效和健壮的代码至关重要。正确的应用这些概念,有助于避免程序中的错误和内存泄漏。通过实践和经验积累,可以更好地理解Python的内存模型,并编写出更优质的代码。
18 2
|
2月前
|
NoSQL Java 测试技术
Golang内存分析工具gctrace和pprof实战
文章详细介绍了Golang的两个内存分析工具gctrace和pprof的使用方法,通过实例分析展示了如何通过gctrace跟踪GC的不同阶段耗时与内存量对比,以及如何使用pprof进行内存分析和调优。
55 0
Golang内存分析工具gctrace和pprof实战
|
1月前
使用qemu来dump虚拟机的内存,然后用crash来分析
使用qemu来dump虚拟机的内存,然后用crash来分析
|
2月前
|
搜索推荐 Java API
Electron V8排查问题之分析 node-memwatch 提供的堆内存差异信息来定位内存泄漏对象如何解决
Electron V8排查问题之分析 node-memwatch 提供的堆内存差异信息来定位内存泄漏对象如何解决
44 0
|
2月前
|
监控 Java
JAVA性能优化- IntelliJ插件:java内存分析工具(JProfiler)
JAVA性能优化- IntelliJ插件:java内存分析工具(JProfiler)
80 0

热门文章

最新文章

下一篇
无影云桌面