昇腾社区首页
中文
注册

内存使用

内存概念

图1 内存示意图

DataFlow中的内存一般需要区分两个概念:

  • mbuf内存:在DataFlow的内存分配场景中,mbuf是驱动对于内存管理的统一机制,所有的flowMsg都会在mbuf池中进行生成并使用。每个flowMsg都会申请一段mbuf内存。其中需要注意,mbuf里面包含了MbufHead和MbufData两部分数据。
    • MbufHead:即数据头,包含了以下几类数据:
      • 基础的数据内容:比如DataType/DataSize/Shape等信息。
      • 数据传递涉及的关键信息:retCode/routeLabel等框架相关信息。
      • 其他用户可配置字段:starttime/endtime/userdata等。
    • MbufData:即数据本体,一段Mbuf上的内存,存储了实际上有效的数据内容
  • 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;
}