From 6be2c6bb6410d472901592b65d17294a7214073e Mon Sep 17 00:00:00 2001 From: zhangzhaoju Date: Thu, 29 Jul 2021 14:50:08 +0800 Subject: [PATCH] memory Leak fix Fix shared_ptr Loop of FuncGraphAbstactClosur->AnalysisContext->children_cache_->ArgsSpec->FuncGraphAbstactClosur. --- mindspore/ccsrc/pipeline/jit/pipeline.cc | 1 + .../jit/static_analysis/static_analysis.cc | 1 + mindspore/core/abstract/analysis_context.cc | 27 ++++++++++++++++--- mindspore/core/abstract/analysis_context.h | 10 ++++++- 4 files changed, 34 insertions(+), 5 deletions(-) diff --git a/mindspore/ccsrc/pipeline/jit/pipeline.cc b/mindspore/ccsrc/pipeline/jit/pipeline.cc index 2c11c24805e..c2d841d5b35 100644 --- a/mindspore/ccsrc/pipeline/jit/pipeline.cc +++ b/mindspore/ccsrc/pipeline/jit/pipeline.cc @@ -1327,6 +1327,7 @@ void ClearResAtexit() { ReleaseGeTsd(); parse::python_adapter::ResetPythonScope(); abstract::AnalysisResultCacheMgr::GetInstance().Clear(); + abstract::AnalysisContext::ClearContext(); #ifdef ENABLE_DEBUGGER Debugger::GetInstance()->Reset(); #endif diff --git a/mindspore/ccsrc/pipeline/jit/static_analysis/static_analysis.cc b/mindspore/ccsrc/pipeline/jit/static_analysis/static_analysis.cc index 103503bf8da..d7fc9b36581 100644 --- a/mindspore/ccsrc/pipeline/jit/static_analysis/static_analysis.cc +++ b/mindspore/ccsrc/pipeline/jit/static_analysis/static_analysis.cc @@ -382,6 +382,7 @@ void AnalysisEngine::ClearEvaluatorCache() { void AnalysisEngine::Clear() { AnalysisResultCacheMgr::GetInstance().Clear(); + AnalysisContext::ClearContext(); anfnode_config_map_.clear(); eval_trace_.clear(); evaluators_.clear(); diff --git a/mindspore/core/abstract/analysis_context.cc b/mindspore/core/abstract/analysis_context.cc index 5f52a9ff2ac..913947cdfba 100644 --- a/mindspore/core/abstract/analysis_context.cc +++ b/mindspore/core/abstract/analysis_context.cc @@ -23,6 +23,7 @@ namespace mindspore { namespace abstract { +std::list AnalysisContext::all_context_; AnalysisContextPtr AnalysisContext::NewContext(const FuncGraphPtr &func_graph, const AbstractBasePtrList &args_spec_list) { // Find func graph's parent and its parent context firstly. @@ -56,7 +57,7 @@ AnalysisContextPtr AnalysisContext::NewContext(const FuncGraphPtr &func_graph, } // Create a new context for the func graph and its specific arguments. - AnalysisContextPtr new_context = std::make_shared(parent_context, func_graph, args_spec_list); + AnalysisContextPtr new_context = CreateContext(parent_context, func_graph, args_spec_list); // To avoid cycle-reference, use weak_ptr here. auto weak_new_context = std::weak_ptr(new_context); new_context->extant_context_cache_[func_graph] = weak_new_context; @@ -102,7 +103,7 @@ AnalysisContextPtr AnalysisContext::FindOwnOrParentContext(const FuncGraphPtr &f } AnalysisContextPtr AnalysisContext::DummyContext() { - AnalysisContextPtr dummy_context = std::make_shared(nullptr, nullptr, AbstractBasePtrList()); + AnalysisContextPtr dummy_context = CreateContext(nullptr, nullptr, AbstractBasePtrList()); dummy_context->extant_context_cache_[nullptr] = std::weak_ptr(dummy_context); return dummy_context; } @@ -115,7 +116,7 @@ bool AnalysisContext::IsDummyContext() { } const AnalysisContextPtr kDummyAnalysisContext = - std::make_shared(nullptr, nullptr, AbstractBasePtrList()); + AnalysisContext::CreateContext(nullptr, nullptr, AbstractBasePtrList()); bool AnalysisContext::operator==(const AnalysisContext &other) const { if (func_graph_ != other.func_graph_) { @@ -177,7 +178,7 @@ AnalysisContextPtr AnalysisContext::SpecializeKey() const { } return arg; }); - AnalysisContextPtr context_new = std::make_shared(nullptr, func_graph_, args_broad_shp); + AnalysisContextPtr context_new = CreateContext(nullptr, func_graph_, args_broad_shp); context_new->parent_ = parent_; return context_new; } @@ -212,5 +213,23 @@ std::string AnalysisContext::ToString() const { buffer << "}"; return buffer.str(); } + +void AnalysisContext::ClearContext() { + for (auto &item : all_context_) { + item->parent_ = nullptr; + item->func_graph_ = nullptr; + item->args_spec_list_.clear(); + item->extant_context_cache_.clear(); + item->children_cache_.clear(); + } + all_context_.clear(); +} + +AnalysisContextPtr AnalysisContext::CreateContext(const AnalysisContextPtr &parent, const FuncGraphPtr &fg, + const AbstractBasePtrList &args_spec_list) { + auto context = std::make_shared(parent, fg, args_spec_list); + all_context_.emplace_back(context); + return context; +} } // namespace abstract } // namespace mindspore diff --git a/mindspore/core/abstract/analysis_context.h b/mindspore/core/abstract/analysis_context.h index e097888ebc7..926697b5759 100644 --- a/mindspore/core/abstract/analysis_context.h +++ b/mindspore/core/abstract/analysis_context.h @@ -22,6 +22,7 @@ #include #include #include +#include #include "abstract/abstract_value.h" #include "ir/meta_func_graph.h" @@ -42,7 +43,6 @@ class AnalysisContext { extant_context_cache_ = parent_->extant_context_cache_; } } - ~AnalysisContext() = default; // Extend this context with values for another graph. @@ -59,6 +59,9 @@ class AnalysisContext { std::string ToString() const; AnalysisContextPtr SpecializeKey() const; AbstractBasePtrList args_spec_list() { return args_spec_list_; } + static void ClearContext(); + static AnalysisContextPtr CreateContext(const AnalysisContextPtr &parent, const FuncGraphPtr &fg, + const AbstractBasePtrList &args_spec_list); private: AnalysisContextPtr parent_; @@ -70,6 +73,11 @@ class AnalysisContext { // Record all created child contexts from this context. // Like: key: [func_graph & arguments], value: [child_context] std::unordered_map children_cache_; + + // There may may be shared_ptr loop like: + // FuncGraphAbstactClosur->AnalysisContext->children_cache_->ArgsSpec->FuncGraphAbstactClosur. + // For break the loop, using all_context_ to clear context_. + static std::list all_context_; }; struct ContextHasher {