In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-02-28 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >
Share
Shulou(Shulou.com)06/01 Report--
This article mainly explains "how to realize the citation count of Android". Interested friends may wish to take a look. The method introduced in this paper is simple, fast and practical. Let's let the editor take you to learn "how to realize the citation count of Android".
1: problem
Unlike java, a language in which runtime provides memory recovery mechanism, what often bothers developers in c C++ development is the allocation and recovery of variables. When new objects and forget delete, memory leaks will occur. If delete is still referenced elsewhere as an object, a wild pointer will be formed.
2: solve
A memory recycling strategy is called reference counting. When an object is referenced, the reference count is + 1, when it is no longer referenced, the reference count is-1, and when the reference count is 0, the object is recycled. The problem with this memory recycling mechanism is that it can not recycle the circular referenced object. If the an object has the reference of the b object, and the b object holds the reference of the an object, there will be a situation that the number of references to the aline b object can never be zero.
Android's simplest reference count implementation template class LightRefBase {public: inline LightRefBase (): mCount (0) {} inline void incStrong (_ _ attribute__ (unused)) const void* id) const {mCount.fetch_add (1, std::memory_order_relaxed) } inline void decStrong (_ _ attribute__ ((unused)) const void* id) const {if (mCount.fetch_sub (1, std::memory_order_release) = = 1) {std::atomic_thread_fence (std::memory_order_acquire); delete static_cast (this);}} / /! DEBUGGING ONLY: Get current strong ref count. Inline int32_t getStrongCount () const {return mCount.load (std::memory_order_relaxed);} typedef LightRefBase basetype;protected: inline ~ LightRefBase () {} private: friend class ReferenceMover Inline static void renameRefs (size_t / * renamer*/) {} inline static void renameRefId (T* / * ref*/, const void* / * old_id*/, const void* / * new_id*/) {} private: mutable std::atomic mCount;}
Only by the value of ±mCount to determine whether the variable has reference references, if the number of references drops to zero, delete static_cast (this) will be called; destructor
Intelligent pointer
Sp strongPointer
Wp weakPointer
The common base class of these two classes is refbase.cpp
Use the scene:
There is often the following usage in framework native code
Sp proc = ProcessState::self (); sp ProcessState::self () {Mutex::Autolock _ l (gProcessMutex); if (gProcess! = nullptr) {return gProcess;} gProcess = new ProcessState (kDefaultDriver); return gProcess;}
Initialize sp with the = operator
Template templatesp& sp::operator = (sp&& other) {T * oldPtr (* const_cast (& m_ptr)); if (m_ptr) massiptra-> decStrong (this); if (oldPtr! = * const_cast (& m_ptr)) sp_report_race (); m_ptr = other.m_ptr; other.m_ptr = nullptr; return * this;}
Mptr is a pointer to a generic type, which is a derivative of the RefBase type. DecStrong if there is a value before, and point m_ptr to a derived class of the new RefBase type
The following details the incStrong and decStrong of RefBase and the incWeak and decWeak methods of WeakRef_type, the whole calculation method of reference counting and the object construction caused by reference counting, and destructions all focus on these four methods.
Pay special attention to
RefBase reference type definition
Enum {OBJECT_LIFETIME_STRONG = 0x0000, OBJECT_LIFETIME_WEAK = 0x0001, OBJECT_LIFETIME_MASK = 0x0001}
And four member variables of the weakRef_impl class
Std::atomic mStrong; / / Thread Atomic Operation variable std::atomic mWeak; / / Thread Atomic Operation variable RefBase* const mBase; std::atomic mFlags; / / Thread Atomic Operation variable explicit weakref_impl (RefBase* base): mStrong (INITIAL_STRONG_VALUE), mWeak (0), mBase (base), mFlags (0) {}
IncWeak
Void RefBase::weakref_type::incWeak (const void* id) {weakref_impl* const impl = static_cast (this); impl- > addWeakRef (id); / / non-debug mode does nothing const int32_t c _ unused = impl- > mWeak.fetch_add (1, std::memory_order_relaxed); / / impl variable mWeak thread safety mode + 1 ALOG_ASSERT (c > = 0, "incWeak called on% p after last weakref", this);}
IncStrong
Void RefBase::incStrong (const void* id) const {weakref_impl* const refs = mRefs; refs- > incWeak (id); / / if reference count refs- > addStrongRef (id); const int32_t c = refs- > mStrong.fetch_add (1, std::memory_order_relaxed); / / mStrong member variable + 1 if (c! = INITIAL_STRONG_VALUE) {/ / return return directly if it is not the first strong reference count } / / if it is the first time, the initial value of mStrong will be subtracted, that is, its value will be calculated from 1, int32_t old _ unused = refs- > mStrong.fetch_sub (INITIAL_STRONG_VALUE, std::memory_order_relaxed); ALOG_ASSERT (old > INITIAL_STRONG_VALUE, "0x%x too small", old); refs- > mBase- > onFirstRef (); / / callback onFirstRef} for the first time
DecWeak
Void RefBase::weakref_type::decWeak (const void* id) {weakref_impl* const impl = static_cast (this); impl- > removeWeakRef (id); const int32_t c = impl- > mWeak.fetch_sub (1, std::memory_order_release); / / mWeak variable value thread safe-1 if (c! = 1) return / / if the reference count value is > 1 and more than one sp references to this variable, then return / / if this is the last reference atomic_thread_fence (std::memory_order_acquire); int32_t flags = impl- > mFlags.load (std::memory_order_relaxed); if ((flags&OBJECT_LIFETIME_MASK) = = OBJECT_LIFETIME_STRONG) {/ / This is the regular lifetime case. The object is destroyed / / when the last strong reference goes away. Since weakref_impl / / outlives the object, it is not destroyed in the dtor, and / / we'll have to do it here. If (impl- > mStrong.load (std::memory_order_relaxed) = = INITIAL_STRONG_VALUE) {/ / if mstrong is the initial value, that is, incStrong / / Decrementing a weak count to zero when object never had a strong / / reference has not been executed. We assume it acquired a weak reference early, e.g. / / in the constructor, and will eventually be properly destroyed, / / usually via incrementing and decrementing the strong count. / / Thus we no longer do anything here. We log this case, since it / / seems to be extremely rare, and should not normally occur. We / / used to deallocate mBase here, so this may now indicate a leak. ALOGW ("RefBase: Object at% p lost last weak reference"before it had a strong reference", impl- > mBase);} else {delete impl;}} else {/ / This is the OBJECT_LIFETIME_WEAK case. The last weak-reference / / is gone, we can destroy the object. / / if it is a weak reference and is the last reference, the onLastWeakRef method impl- > mBase- > onLastWeakRef (id) will be called back; delete impl- > mBase; / / destructing the object itself}}
Destructor function
RefBase::~RefBase () {int32_t flags = mRefs- > mFlags.load (std::memory_order_relaxed); / / Life-time of this object is extended to WEAK, in / / which case weakref_impl doesn't out-live the object and we / / can free it now. If ((flags & OBJECT_LIFETIME_MASK) = = OBJECT_LIFETIME_WEAK) {/ / It's possible that the weak count is not 0 if the object / / re-acquired a weak reference in its destructor / / if it is weak and the reference count is 0 if (mRefs- > mWeak.load (std::memory_order_relaxed) = = 0) {delete mRefs / / Deconstruct impl class}} else if (mRefs- > mStrong.load (std::memory_order_relaxed) = = INITIAL_STRONG_VALUE) {/ / We never acquired a strong reference on this object. LOG_ALWAYS_FATAL_IF (mRefs- > mWeak.load ()! = 0, "RefBase: Explicit destruction with non-zero weak"reference count"); / / TODO: Always report if we get here. Currently MediaMetadataRetriever / / C++ objects are inconsistently managed and sometimes get here. / / There may be other cases, but we believe they should all be fixed. Delete mRefs;} / / For debugging purposes, clear mRefs. Ineffective against outstanding wp's. Const_cast (mRefs) = nullptr;} at this point, I believe you have a deeper understanding of "how to realize the reference count of Android". You might as well do it in practice. Here is the website, more related content can enter the relevant channels to inquire, follow us, continue to learn!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.