ProtoBuf - Arena
1、概述
最近看 Protocal Buffer 的源码,初次见到这个库源自陈硕的 muduo ,便打算看一看,在此做一下记录。官网文档不能访问,只能凭借代码的自己理解,查看的源码版本为 3.6.0。
初识 Arena 时,发现是个 allocator。Arena 每次分配一大块内存,使用时在已经分配的内存块上获取,用来代替 new/delete 的堆上分配。通过一次申请大块内存,并且一次性释放,同时可取消调用对象的析构函数来提升效率。
Arena 线程安全:多个线程可并发在Arena分配空间。但销毁时非线程安全,销毁线程必须和Arena 的使用者同步。
2、特点
Arena 分配器使用 CreateMessage<T> 接口创建消息:
-类型 T 必须(至少)有两个构造函数:1 不含参数的构造函数,当在堆上分配时使用; 2 含 google::protobuf::Arena* 参数的构造函数,在Arena上分配时使用。当第二种情况传入空指针时,与第一种情况相同。
-类型 T 必须有特殊的特点:定义类型 |InternalArenaConstructable_|。一般被定义为 typedef void 类型。如果没有会在编译时报错。实现在 InternalHelper 模板类中,具体代码如下。
1 template <typename U> 2 static char ArenaConstructable(const typename U::InternalArenaConstructable_*); 4 template <typename U> 5 static double ArenaConstructable(...); 6 7 typedef std::integral_constant<bool, sizeof(ArenaConstructable<T>( 8 static_cast<const T*>(0))) == 9 sizeof(char)> 10 is_arena_constructable;
-类型T还 *可以* 有特征:| DestructorSkippable_|。如果该类型被定义,在传入非空 Arena指针时,对象的析构函数不会被调用。如果没有该特征,则在Arena销毁时,对象的析构函数一定会被调用。实现方法与上面类似。
1 template <typename U> 2 static char DestructorSkippable(const typename U::DestructorSkippable_*); 3 template <typename U> 4 static double DestructorSkippable(...); 5 6 typedef std::integral_constant< 7 bool, sizeof(DestructorSkippable<T>(static_cast<const T*>(0))) == 8 sizeof(char) || 9 std::is_trivially_destructible<T>::value> 10 is_destructor_skippable;
在 proto 文件中, 设置 option cc_enable_arenas = true; 则使用 Arena 分配器。此时在使用 protoc 编译器生成 pb.h 的代码中会有 InternalArenaConstructable_ 和 DestructorSkippable_的定义,如
1 typedef void InternalArenaConstructable_; 2 typedef void DestructorSkippable_;
3、实现
Arena 的实现在 arena.h arena.cc arena_impl.h 中,同时还有专门的字符串域的实现在 arenastring.h 中。其中arena_impl 中是实现存储分配的核心代码,是arena中一个对象。
Arena 的内存结构如下图所示,图使用 Dia 绘制。每个线程都会分配一个Block,在Block上分配一个 SerialArena。Block是个链表结构,在空间分配时,如果该Block空间不够用,则新建一个Block,新Block的大小是旧Block的二倍,同时新Block的next指向旧 Block。一个线程在获取 Arena 时,如果该线程还没分配 Block,则申请一个Block,在该Block上分配 SerialArena,该SerialArena 的 next 指向上个线程的 SerialArena。
在 ArenaImpl 销毁时,首先进行 Cleanup,然后释放所有空间。Cleanup是根据添加的 Cleanup 表,顺序调用各个对象的 cleanup 函数,Cleanup 列表如下图所示。释放空间时会循环销毁每个 SerialArena 的所有 Block。
暂时先写到这里吧。
转载于:https://www.cnblogs.com/sun-shy/p/9775346.html
ProtoBuf - Arena相关推荐
- Protobuf Arena 教程
arena 直译为"竞技场",很多工程里都有这个概念,如LevelDB中. 在google/protobuf下,提供了arena,可以取代堆作为消息的缓存. 主要的api介绍文档: ...
- gRPC快速入门(三)——Protobuf应用示例
gRPC快速入门(三)--Protobuf应用示例 一.Protobuf使用流程 在工程开发中使用Protobuf流程如下: (1)定义proto描述文件,以proto作为后缀名. (2)使用Prot ...
- caffe安装错误(补充)protobuf
之前在https://blog.csdn.net/uniqueyyc/article/details/83338889,这个里面已经列出错误并解决了.但是过了些天,想要重新编译时发现又会出错,我猜想可 ...
- Cartographer安装
请注意本文的安装日期2017/12/20,如果距离该时间很遥远,请仅作为参考,毕竟cartographer的代码在不断更新,可能会存在很大的变动. 参考文档: https://google-carto ...
- 深度学习_21天实战Caffe.pdf
深度学习_21天实战Caffe.pdf 原 深度学习21天实战caffe学习笔记<1:深度学习的过往> 1. 深度学习DL: 1.1.有监督学习.无监督学习.过拟合.训练样本.泛化.训练集 ...
- [C++][muduo]1-muduo安装和运行
muduo安装和运行 为补充C++工程知识近期打算学习muduo源码,下面记录muduo源码编译链接及运行过程. 0.版本 操作系统ubuntu 14.04及以上,gcc-8.3.0,cmake-3. ...
- orb-slam3安装编译运行。opencv3.2 undefined reference to `cblas_zgemm vgg_generated_48.i ippicv_linux_20151
orbslam2的项目完成了,现在需要搞多传感器了orbslam3是比较合适的框架. downloand detail comment opencv安装 ubuntu16 编译安装boost1.69与 ...
- 百度 C++ 工程师的那些极限优化(内存篇)
c/c++ linux服务器开发相关视频解析: c/c++程序员必知的内存泄漏解决方案与原理实现 90分钟了解Linux内存架构,numa的优势,slab的实现,vmalloc的原理 c/c++ li ...
- AM5728开发深度学习之安装 caffe-jacinto
AM5728开发深度学习之安装 caffe-jacinto--WizNote笔记 要先使用自己训练的模型,可以使用caffe和Tensorflow,但是使用TI的caffe-jacinto能让训练的模 ...
最新文章
- 程序员看过这篇文章 让你学会阅读源码!
- BAT 批处理命令 - 获取时间并进行自定义年月日、时分秒格式实例演示
- [Hbase]Hbase章2 Hbase读写过程解析
- docker容器间双向通信(基于Bridge网桥)
- eclipse new creation file type
- 分析Oracle有时会用索引来查找数据的原因-oracle执行计划
- ProjectFileManager 发布!项目文件管理效率提升10倍以上!
- Python案例:获取天气信息并绘制气温折线图
- 如何将Sublime Text中的代码以彩色高亮形式复制到博客或word文档里
- CAN FD:测量和重编程
- 用R进行meta分析(metafor包)
- Unity 基础 之 Camera摄像机属性介绍
- 双线性的定义以及他的性质
- [裴礼文数学分析中的典型问题与方法习题参考解答]4.4.9
- 有关微博营销的社交营销打法
- 人体如何区分阴虚和阳虚?
- 机器人 瓷砖墙面清洗_墙壁清洁机器人
- mark:Kafka
- 区块链技术--Ethereum(以太坊)
- 【自动驾驶】碰撞检测算法