内存使用
内存概念
图1 内存示意图


DataFlow中的内存一般需要区分两个概念:
- mbuf内存:在DataFlow的内存分配场景中,mbuf是驱动对于内存管理的统一机制,所有的flowMsg都会在mbuf池中进行生成并使用。每个flowMsg都会申请一段mbuf内存。其中需要注意,mbuf里面包含了MbufHead和MbufData两部分数据。
- MbufHead:即数据头,包含了以下几类数据:
- 基础的数据内容:比如DataType/DataSize/Shape等信息。
- 数据传递涉及的关键信息:retCode/routeLabel等框架相关信息。
- 其他用户可配置字段:starttime/endtime/userdata等。
- MbufData:即数据本体,一段Mbuf上的内存,存储了实际上有效的数据内容
- MbufHead:即数据头,包含了以下几类数据:
- os内存:其他的用户内存。
-【PS】【非常重要】:emptyMsg上是没有MbufData的,c++获得的就是一个nullptr
mbuf内存使用注意事项
在使用过程中,FlowMsg的使用与释放取决于该FlowMsg的作用域,作用域的概念包含在FlowGraph和UDF上。
FlowMsg被释放需要满足两个条件:
- 这个FlowMsg在FlowGraph上不再被别的UDF使用。
- 这个FlowMsg在当前UDF内,不会因为智能指针等原因被持续持有。
FlowMsg的释放过程中需要注意:
- FlowMsg的指针本身被释放时,其内存对于mbuf管理机制来说已经失效,可被复用。因此,其MbufData所包含的信息在指针释放时会存在不可靠性。
- 每次UDF执行结束时,其中临时申请的指针就会被释放掉。
使用样例
指针未被释放导致的内存泄露
在Proc执行结束时,如果不将A置位nullptr,则其持有的智能指针则不会释放,会长期持有,产生内存泄漏。
class A { int32_t Proc(...) { A = xxx; B = func(A); // A = nullptr; } private: std::shared_ptr<FlowFunc::FlowMsg> A; }
指针离开作用域,而内容继续被使用
在Proc执行结束时,cv::Mat A的数据来自于inputA的mbufData。当func执行结束时,inputA已被释放。此时inputA对应的mbufData可被别的FlowMsg使用。即cv::Mat A由于仅是指针,已失去可信度。
class A { int32_t Proc(...) { A = func(xxx); B = funcA(A); } cv::Mat func(...) { inputA = FlowFunc::FlowMsg xxx; A = get_tensor(inputA); return A; } private: cv::Mat A; }
父主题: 相关概念