亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Android智能指針輕量級(jí)Light Pointer初識(shí)

 更新時(shí)間:2022年12月09日 16:16:07   作者:一只藍(lán)鯨  
這篇文章主要為大家介紹了Android智能指針輕量級(jí)Light Pointer初識(shí)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

引言

相信有很多小伙伴跟我一樣,一直從事Android上層應(yīng)用開發(fā),對(duì)Android底層充滿興趣,奈何基礎(chǔ)知識(shí)薄弱,每次學(xué)習(xí)源碼進(jìn)入native層的時(shí)候,都想放棄。不用灰心,一遍看不懂就再來一遍,今天主要是分享Android智能指針的內(nèi)容。

作為上層應(yīng)用開發(fā)者對(duì)C++不是很熟悉,不要慌,咱們一步一步來,接下來我將分為3篇文章來講解智能指針

1、智能指針初探——輕量級(jí)指針(Light Pointer)

2、智能指針初探——強(qiáng)指針(Strong Pointer)(未更新)

3、智能指針初探——弱指針(Weak Pointer)(未更新)

本篇是智能指針初探——輕量級(jí)指針(Light Pointer),在講解智能指針之前我們先思考下為什么java沒有指針。

java

做Android上層應(yīng)用開發(fā)肯定離不開java,很多人選擇學(xué)習(xí)java最主要的原因是沒有指針,再也不用擔(dān)心各種指針和內(nèi)存釋放了。

//java 
Object a = new Object(); 

java在設(shè)計(jì)中盡量淡化了指針的概念,我們可以簡(jiǎn)單的new對(duì)象,上面示例代碼就是java生成一個(gè)對(duì)象的最簡(jiǎn)單樣例,我們可以通過變量a去使用剛剛new好的Object對(duì)象。變量a是一個(gè)對(duì)象類型或者說是引用類型,作用其實(shí)跟C/C++中的指針類似。

java中引用分為如下4類,感興趣的同學(xué)可以自行去學(xué)習(xí):

引用類型概述
StrongReference(強(qiáng)引用)強(qiáng)引用是最經(jīng)常使用的一種引用,如new操作創(chuàng)建的對(duì)象就屬于強(qiáng)引用,只要強(qiáng)引用關(guān)系還存在,垃圾收集器就不會(huì)回收掉被引用的對(duì)象。
SoftReferenc(軟引用)內(nèi)存空間足夠,垃圾回收器就不會(huì)回收它,如果內(nèi)存空間不足了,就會(huì)回收這些對(duì)象的內(nèi)存,只要垃圾回收器沒有回收它,該對(duì)象就可以被程序使用。
WeakReferenc(弱引用)弱引用也是用來描述那些非必須對(duì)象,但是它的強(qiáng)度比軟引用更弱一些,被弱引用關(guān)聯(lián)的對(duì)象只能生存到下一次垃圾收集發(fā)生為止。當(dāng)垃圾收集器開始工作,無論當(dāng)前內(nèi)存是否足夠,都會(huì)回收掉只 被弱引用關(guān)聯(lián)的對(duì)象
PhantomReference(虛引用)虛引用也稱為“幽靈引用”或者“幻影引用”,它是最弱的一種引用關(guān)系。一個(gè)對(duì)象是否有虛引用的 存在,完全不會(huì)對(duì)其生存時(shí)間構(gòu)成影響,也無法通過虛引用來取得一個(gè)對(duì)象實(shí)例。為一個(gè)對(duì)象設(shè)置虛 引用關(guān)聯(lián)的唯一目的只是為了能在這個(gè)對(duì)象被收集器回收時(shí)收到一個(gè)系統(tǒng)通知。

這些引用類型配合Java垃圾回收機(jī)制(GC),讓我們java程序員不用太關(guān)心內(nèi)存的釋放。Java垃圾回收機(jī)制正是由java虛擬機(jī)(JVM)提供,在Android也有對(duì)應(yīng)的虛擬機(jī):Dalvik 虛擬機(jī)(Dalvik Virtual Machine),ART(Android Runtime)虛擬機(jī)。 java在進(jìn)行垃圾回收機(jī)制(GC)時(shí),需要做兩件事:

1、判斷該對(duì)象是否為垃圾

2、垃圾回收的具體算法

判斷該對(duì)象是否為垃圾

1、引用計(jì)數(shù)法

原理其實(shí)很簡(jiǎn)單,給運(yùn)行的對(duì)象添加一個(gè)引用計(jì)數(shù)器,每當(dāng)有一個(gè)地方引用它時(shí),計(jì)數(shù)器+1;當(dāng)引用失效時(shí),計(jì)數(shù)器就-1,任何時(shí)刻計(jì)數(shù)器為0的對(duì)象,就視作不可能再被使用。這一種方式,實(shí)現(xiàn)簡(jiǎn)單,邏輯也清晰,大部分的情況下,它都可以達(dá)到很好的效果,盡管這樣,計(jì)數(shù)器算法還是存在但是的,但是它無法解決循環(huán)引用的場(chǎng)景(A、B兩個(gè)對(duì)象相互引用)。

2、可達(dá)性分析法

通過一系列稱為“GC Roots”的對(duì)象作為起始點(diǎn),從這些節(jié)點(diǎn)開始向下搜索,搜索走過的路徑稱為“引用鏈”,當(dāng)一個(gè)對(duì)象到 GC Roots 沒有任何的引用鏈相連時(shí)(從 GC Roots 到這個(gè)對(duì)象不可達(dá))時(shí),證明此對(duì)象不可用。

GC Roots包含以下:

  • 虛擬機(jī)棧(棧幀中的本地變量表)中引用的對(duì)象
  • 方法區(qū)中類靜態(tài)屬性引用的對(duì)象
  • 方法區(qū)中常量引用的對(duì)象
  • 本地方法棧中JNI(即一般說的native方法)中引用的對(duì)象

......

雖然這些虛擬機(jī)已幫忙我們回收內(nèi)存,但其實(shí)我們做上層應(yīng)用開發(fā)時(shí)還是得特別需要注意引用,不然還是會(huì)造成OOM等異常。

垃圾回收的具體算法

java垃圾回收的算法有很多這里就不詳細(xì)展開了(標(biāo)記-清除算法、 標(biāo)記-整理算法、 復(fù)制算法、分代收集算法...),感興趣的同學(xué)可以自行學(xué)習(xí)

C++

相比較java的引用+垃圾回收機(jī)制,C++沒有垃圾回收的機(jī)制,通常使用引用計(jì)數(shù)的方法來統(tǒng)計(jì)對(duì)象的使用情況,為了實(shí)現(xiàn)引用計(jì)數(shù),需要有個(gè)類來負(fù)責(zé)計(jì)數(shù),我們先看下最簡(jiǎn)單的輕量級(jí)指針(Light Pointer)。

本文中的源代碼可下面鏈接查看:

www.aospxref.com/android-7.1…

www.aospxref.com/android-7.1…

www.aospxref.com/android-7.1…

輕量級(jí)指針(Light Pointer)

我們希望指針指向的對(duì)象有引用計(jì)數(shù)功能,當(dāng)計(jì)數(shù)為0時(shí),刪除對(duì)象,所以需要有個(gè)類能夠?qū)崿F(xiàn)引用計(jì)數(shù)的功能。

輕量級(jí)指針(Light Pointer)的引用計(jì)數(shù)類就是它:LightRefBase(system/core/include/utils/RefBase.h)

template <class T>
class LightRefBase
{
public:
    inline LightRefBase() : mCount(0) { }
    inline void incStrong(const void* id) const {
        android_atomic_inc(&mCount);
    }
    inline void decStrong(const void* id) const {
        if (android_atomic_dec(&mCount) == 1) {
            delete static_cast<const T*>(this);
        }
    }
    //! DEBUGGING ONLY: Get current strong ref count.
    inline int32_t getStrongCount() const {
        return mCount;
    }
protected:
    inline ~LightRefBase() { }
private:
    mutable volatile int32_t mCount;
};

我們簡(jiǎn)單看下這個(gè)類,重點(diǎn)關(guān)注mCount這個(gè)變量的使用,在incStrong中+1,在decStrong是-1(當(dāng)前mCount為1時(shí),再減就要為0了,就會(huì)delete對(duì)象)。

好了,現(xiàn)在我們有了引用計(jì)數(shù)類之后,還缺少一個(gè)關(guān)鍵角色:指針sp(system/core/include/utils/StrongPointer.h)

template<typename T>
class sp {
public:
    inline sp() : m_ptr(0) { }
    sp(T* other);
    sp(const sp<T>& other);
    sp(sp<T>&& other);
    template<typename U> sp(U* other);
    template<typename U> sp(const sp<U>& other);
    template<typename U> sp(sp<U>&& other);
    ~sp();
    // Assignment
    sp& operator = (T* other);
    sp& operator = (const sp<T>& other);
    sp& operator = (sp<T>&& other);
    template<typename U> sp& operator = (const sp<U>& other);
    template<typename U> sp& operator = (sp<U>&& other);
    template<typename U> sp& operator = (U* other);
    //! Special optimization for use by ProcessState (and nobody else).
    void force_set(T* other);
    // Reset
    void clear();
    // Accessors
    inline  T&      operator* () const  { return *m_ptr; }
    inline  T*      operator-> () const { return m_ptr;  }
    inline  T*      get() const         { return m_ptr; }
    // Operators
    COMPARE(==)
    COMPARE(!=)
    COMPARE(>)
     COMPARE(<)
     COMPARE(<=)
     COMPARE(>=)
 private:
     template<typename Y> friend class sp;
     template<typename Y> friend class wp;
     void set_pointer(T* ptr);
     T* m_ptr;
 };

sp類是個(gè)模版類,主要的工作就是指針指向m_ptr,在構(gòu)造函數(shù)、析構(gòu)函數(shù)、重載函數(shù)(operator =)中控制m_ptr中的計(jì)數(shù),而m_ptr指向的對(duì)象就是繼承自LightRefBase。

//以下只截取了部分代碼,詳細(xì)代碼內(nèi)容參考 StrongPointer.h
//普通構(gòu)造函數(shù)
template<typename T>
 sp<T>::sp(T* other)
         : m_ptr(other) {
     if (other)
         other->incStrong(this);
 }
//拷貝構(gòu)造函數(shù)
 template<typename T>
 sp<T>::sp(const sp<T>& other)
         : m_ptr(other.m_ptr) {
     if (m_ptr)
         m_ptr->incStrong(this);
 }
//析構(gòu)函數(shù)
 template<typename T>
 sp<T>::~sp() {
     if (m_ptr)
         m_ptr->decStrong(this);
 }
//重載函數(shù)(operator =)
 template<typename T>
 sp<T>& sp<T>::operator =(const sp<T>& other) {
     T* otherPtr(other.m_ptr);
     if (otherPtr)
         otherPtr->incStrong(this);
     if (m_ptr)
         m_ptr->decStrong(this);
     m_ptr = otherPtr;
     return *this;
 }

那么我們?cè)撊绾问褂幂p量級(jí)指針(Light Pointer):

只需繼承自LightRefBase結(jié)合sp即可。

class MyLightRefClass : public LightRefBase<MyLightRefClass>
{
public:
        MyLightRefClass()
        {
        }
        virtual ~MyLightRefClass()
        {
        }
};
int main(int argc, char** argv)
{
        MyLightRefClass* lightClass = new MyLightRefClass();
        sp<MyLightRefClass> lp = lightClass;
}

輕量級(jí)指針的分享就結(jié)束了,輕量級(jí)指針很簡(jiǎn)單但是有一個(gè)問題沒有解決:A、B相互引用,關(guān)于后面的強(qiáng)指針、弱指針還請(qǐng)繼續(xù)關(guān)注

以上就是Android智能指針輕量級(jí)Light Pointer初識(shí)的詳細(xì)內(nèi)容,更多關(guān)于Android輕量級(jí)指針Light Pointer的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論