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 模板类中,具体代码如下。

 template <typename U>
static char ArenaConstructable(const typename U::InternalArenaConstructable_*);
template <typename U>
static double ArenaConstructable(...); typedef std::integral_constant<bool, sizeof(ArenaConstructable<T>(
static_cast<const T*>())) ==
sizeof(char)>
is_arena_constructable;

  -类型T还 *可以* 有特征:| DestructorSkippable_|。如果该类型被定义,在传入非空 Arena指针时,对象的析构函数不会被调用。如果没有该特征,则在Arena销毁时,对象的析构函数一定会被调用。实现方法与上面类似。

 template <typename U>
static char DestructorSkippable(const typename U::DestructorSkippable_*);
template <typename U>
static double DestructorSkippable(...); typedef std::integral_constant<
bool, sizeof(DestructorSkippable<T>(static_cast<const T*>())) ==
sizeof(char) ||
std::is_trivially_destructible<T>::value>
is_destructor_skippable;

在 proto 文件中, 设置 option cc_enable_arenas = true; 则使用 Arena 分配器。此时在使用 protoc 编译器生成 pb.h 的代码中会有 InternalArenaConstructable_ 和 DestructorSkippable_的定义,如

 typedef void InternalArenaConstructable_;
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。

  暂时先写到这里吧。







ProtoBuf - Arena的更多相关文章

  1. caffe编译环境的错误:..build_release/src/caffe/proto/caffe.pb.h:23:35: fatal error: google/protobuf/arena.h: 没有那个文件

    在搭建caffe的环境时出现错误: .build_release/src/caffe/proto/caffe.pb.h:23:35: fatal error: google/protobuf/aren ...

  2. fatal error: google/protobuf/arena.h:没有那个文件或目录

    安装caffe时make all会出现这个错误,按照https://github.com/BVLC/caffe/issues/4988说法,可能时libprotobuf-dev过时了,需要从源码重新变 ...

  3. 在UnrealEngine4中使用Google Protobuf

    转自:https://blog.csdn.net/or_7r_ccl/article/details/54986393 在UnrealEngine4中使用Google Protobuf         ...

  4. protobuf ubuntu 18.04环境下安装

    (t20190518) luo@luo-All-Series:~/MyFile$ (t20190518) luo@luo-All-Series:~/MyFile$ (t20190518) luo@lu ...

  5. Proto3:Arena分配指南

    Arena分配是仅C++有的功能,在使用Protocol Buffer时,它可以帮助你优化你的内存使用,提高性能.在.proto文件中启用Arena分配会在生成的C++代码中添加处理Arena分配的额 ...

  6. C++操作Kafka使用Protobuf进行跨语言数据交互

    C++操作Kafka使用Protobuf进行跨语言数据交互 Kafka 是一种分布式的,基于发布 / 订阅的消息系统.主要设计目标如下: 以时间复杂度为 O(1) 的方式提供消息持久化能力,即使对 T ...

  7. [OpenCV] Install OpenCV 3.4 with DNN

    目标定位 一.开始全面支持 Tensorflow OpenCV3.4 新功能 当前最新进展OpenCV 3.4 dev:https://github.com/opencv/opencv/tree/ma ...

  8. ubuntu18.04+ cuda9.0+opencv3.1+caffe-ssd安装

    详细Ubuntu18.04,CUDA9.0,OpenCV3.1,Tensorflow完全配置指南 问题1:使用Cmake编译opencv源码 CMake Error: The following va ...

  9. 记intel杯比赛中各种bug与debug【其二】:intel caffe的使用和大坑

    放弃使用pytorch,学习caffe 本文仅记录个人观点,不免存在许多错误 Caffe 学习 caffe模型生成需要如下步骤 编写network.prototxt 编写solver.prototxt ...

随机推荐

  1. NetBeans IDE For PHP 简体中文版 8.1安装配置

    一.NetBeans IDE For PHP简介 NetBeans IDE 是一个开发环境 - 供程序员编写.编译.调试和部署程序的一个工具. 它是用 Java 编写的 - 但却可以支持任何编程语言. ...

  2. python 面向对象十 __init__和__new__

    一.__init__和__new__方法 __init__ 和 __new__ 最主要的区别在于:1.__init__ 通常用于初始化一个新实例,控制这个初始化的过程,比如添加一些属性, 做一些额外的 ...

  3. bzoj 3784: 树上的路径【点分治+st表+堆】

    参考:https://www.cnblogs.com/CQzhangyu/p/7071477.html 神奇的点分治序(或者叫点剖?).就是把点分治扫过的点依次放进队列里,然后发现,对于每一棵树摊到序 ...

  4. JSON WEB TOKEN 从原理到实战

    阅读本文大概需要 4.2 分钟. 作者:王廷骏原文:https://juejin.im/post/5ce272c1e51d45109b01b0f8 1. JSON WEB TOKEN 1.1 什么是J ...

  5. 扩展KMP的应用

    扩展KMP的应用: 给出模板串S和串T,长度分别为Slen和Tlen,要求在线性时间内,对于每个S[i](0<=i<Slen),求出S[i..Slen-1]与T的 最长公共前缀长度,记为e ...

  6. 题解报告:hdu 1398 Square Coins(母函数或dp)

    Problem Description People in Silverland use square coins. Not only they have square shapes but also ...

  7. Snort里如何将一个tcpdump格式的二进制文件读取打印到屏幕上(图文详解)

    不多说,直接上干货! 关于tcpdump二进制格式,这个基本概念不说. 支持tcpdump二进制格式的嗅探器工具,这里我说两个:tcpdump或者ethereal. [root@datatest Se ...

  8. hbase最近的一些实践

    有一段实践没有写东西了,最近组里面来了两个新的小伙伴,并且一起针对目前的hbase集群做了一些运维和优化实践,比较零散,记录下来供以后以及和大家参考. 1,hbase regionserver宕机导致 ...

  9. C# 控制台语音计算器

    记得上高中时,给人当会计,帮忙结算月度工资:用的就是带语音功能的计算器! 当时用起来倍儿爽,于是速度加倍,效率加速:结果让老板赔了不少钱! 就是因为这个,才对语音计算器有了深刻印象!可能是这货坑了我! ...

  10. A8通用权限框架