C++ 内存管理 之 内存池实现
为什么要实现内存池?
一方面 是为了减少 调用 malloc()
的次数(尽管 malloc()
不慢) 但是调多了 会产生(外碎片)
另一方面 是因为 每次用 malloc()
分配到的内存 是要交税的 就是上一节中讲的 cookie
里面记录着 这一块内存的大小信息(内碎片) 特别是在频繁申请小内存的时候尤为明显
最终 pool_allocator 版本
具体代码可见 Memory_Pool
一方面 是为了减少 调用 malloc()
的次数(尽管 malloc()
不慢) 但是调多了 会产生(外碎片)
另一方面 是因为 每次用 malloc()
分配到的内存 是要交税的 就是上一节中讲的 cookie
里面记录着 这一块内存的大小信息(内碎片) 特别是在频繁申请小内存的时候尤为明显
具体代码可见 Memory_Pool
本文主要讲讲 GNU-C++ 4.9 下的扩展内存分配器
首先 GNU-C++ 4.9 有 7 个扩展的内存分配器
主要看看 pool_allocator
array_allocator
bitmap_allocator
以下源码都可在 .../ext/*.h
下找到 我将其进行了适当的 删减和修改
直接用 ::operator new
和 ::operator delete
实现出来的 好处是 可以被重载 没啥特色
1 | template<typename _Tp> |
本文主要讲的是 各个C++版本 中的STL标准库中的默认内存分配器 的 各种实现
VC6 它什么内存管理都没做 直接调用的 operator new
而 operator new
内部实际上 调用的就是 malloc
此外 VC6 下 是以元素为单位 比如 int 的话 他就会分配 512 ints 如果是 double 则会分配 512 doubles
而 GNU-C++ 2.9
以字节为单位 GNU-C++ 4.9
以元素为单位 在 G2.9 中的容器默认分配器 被移到了 pool_allocator
中
注意 G2.9 的标准分配器 和 容器默认分配器 不一样噢!
std::allocator
标准分配器 也是什么都没做
但是 G2.9
容器使用的分配器 不是上面的那个 std::allocator
而是 std::alloc
因为我觉得这一块是 C++ 自带的表达式 表达式里面 去调用 C语言的 CRT 库中的 malloc
和 free
但这篇 只讲自带的表达式 而不去深究 CRT 中的内存分配函数 所以只叫原生版本
分配 | 释放 | 类属 | 可否重载 |
---|---|---|---|
malloc() | free() | C 函数 | 否 |
new | delete | C++ 表达式 | 否 |
::operator new() | ::operator delete() | C++ 函数 | 可 |
allocator | allocator | C++ 标准库 | 自由设计搭配的容器 |
其中 ::operator new() 和 ::operator delete()
调用了 malloc() 和 free()
1 | void *p1 = malloc(512); |
VSCode 近期推出了 Remote-SSH 这个工具 使得 Linux开发者 能够在本地(Windows 机)上直接对开发机源码进行修改 简直拯救了一大批人啊… 但是却没有提到 如何离线安装 因此本文可能是最早 尝试离线安装的教程
Remote-SSH
插件首先 IPv4 资源是非常稀少的 大约只有 43亿 而且这还是包括了私有IP地址段的 其次 IP地址分为了五类 其中 D类地址没有主机标识 常被用于广播 E类被保留 我们不去管它
那就只剩下了 A B C 三类 问题是 A类和B类的链路允许非常多的计算机连接 实际网络架构上 根本用不到那么多 这就造成了IPv4的浪费 这个时候 子网掩码出现了
将 A B C类网络进行更细的划分 避免浪费 IPv4地址 也可以把小的网络归并成大的网络即超网
假设有一个财主 他有256间房子 房子的编号是 0~255
然后它的房子都在192.168.0
这一条街上 现在他有8
个儿子 要分家 则相当于 每个人都分得32
间房子
在天朝这么久 你曾为网络状况不佳而烦恼过吗? 平时使用的 Shadowsocks 是怎么实现?
这篇讲的就是 如何用 Golang 实现一个最为基础的 Shdowsocks 的功能的软件 我将本文实现的软件取名叫 GoSocksProxy
老规矩先介绍一遍 什么是 GoSocksProxy? 它是怎么来的?
一个 Golang 所写的网络混淆代理 是学习 SOCKS5 协议时的副产品 为此还做了一张图
请把你做的实验代码填入本实验中代码中有“LAB1”/“LAB2”/“LAB3”/“LAB4”/“LAB5”/“LAB6” /“LAB7”的注释相应部分。并确保编译通过。注意:为了能够正确执行lab8的测试应用程序,可能需对已完成的实验1/2/3/4/5/6/7的代码进行进一步改进。
1 | vmm.c default_pmm.c pmm.c proc.c swap_fifo.c trap.c check_sync.c |