Android中通过引用计数来实现智能指针,并且实现有强指针与弱指针。由对象本身来提供引用计数器,但是对象不会去维护引用计数器的值,而是由智能指针来管理。
要达到所有对象都可用引用计数器实现智能指针管理的目标,可以定义一个公共类,提供引用计数的方法,所有对象都去继承这个公共类,这样就可以实现所有对象都可以用引用计数来管理的目标,在Android中,这个公共类就是RefBase,同时还有一个简单版本LightRefBase。
RefBase作为公共基类提供了引用计数的方法,但是并不去维护引用计数的值,而是由两个智能指针来进行管理:sp(Strong Pointer)和wp(Weak Pointer),代表强引用计数和弱引用计数。
一、轻量级引用计数的实现:LightRefBase
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
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; } typedef LightRefBase<T>
basetype; protected : inline ~LightRefBase()
{ } private : mutable volatile int32_t
mCount; }; |
LightRefBase的实现很简单,只是内部保存了一个变量用于保存对象被引用的次数,并提供了两个函数用于增加或减少引用计数。
二、sp(Strong Pointer)
LightRefBase仅仅提供了引用计数的方法,具体引用数应该怎么管理,就要通过智能指针类来管理了,每当有一个智能指针指向对象时,对象的引用计数要加1,当一个智能指针取消指向对象时,对象的引用计数要减1,在C++中,当一个对象生成和销毁时会自动调用(拷贝)构造函数和析构函数,所以,对对象引用数的管理就可以放到智能指针的(拷贝)构造函数和析构函数中。Android提供了一个智能指针可以配合LightRefBase使用:sp,sp的定义如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
template < typename T> class sp { public : inline sp()
: m_ptr(0) { } sp(T*
other); sp( const sp<T>&
other); template < typename U>
sp(U* other); template < typename U>
sp( const sp<U>&
other); ~sp(); //
Assignment sp&
operator = (T* other); sp&
operator = ( const sp<T>&
other); template < typename U>
sp& operator = ( const 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; }; |
代码比较多,其中Accessors部分代码重载了*、->操作符使我们使用sp的时候就像使用真实的对象指针一样,可以直接操作对象的属性或方法,COMPARE是宏定义,用于重载关系操作符,由于对引用计数的控制主要是由(拷贝)构造函数和析构函数控制,所以忽略其他相关代码后,sp可以精简为如下形式(赋值操作符也省略掉了,构造函数省略相似的两个):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
template < typename T> class sp { public : inline sp()
: m_ptr(0) { } sp(T*
other); sp( const sp<T>&
other); ~sp(); private : template < typename Y> friend class sp; template < typename Y> friend class wp; void set_pointer(T*
ptr); T*
m_ptr; }; |
默认构造函数使智能指针不指向任何对象,sp(T* other)与sp(
const
sp<T>& other)
的实现如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
template < typename T> sp<T>::sp(T*
other) :
m_ptr(other) { if (other)
other->incStrong( this ); } template < typename T> sp<T>::sp( const sp<T>&
other) :
m_ptr(other.m_ptr) { if (m_ptr)
m_ptr->incStrong( this ); } |
内部变量m_ptr指向实际对象,并调用实际对象的incStrong函数,T继承自LightRefBase,所以此处调用的是LightRefBase的incStrong函数,之后实际对象的引用计数加1。
当智能指针销毁的时候调用智能指针的析构函数:
1
2
3
4
5
|
template < typename T> sp<T>::~sp() { if (m_ptr)
m_ptr->decStrong( this ); } |
调用实际对象即LightRefBase的decStrong函数,其实现如下:
1
2
3
4
5
|
inline void decStrong( const void *
id) const { if (android_atomic_dec(&mCount)
== 1) { delete static_cast < const T*>( this ); } } |
android_atomic_dec返回mCount减1之前的值,如果返回1表示这次减过之后引用计数就是0了,就把对象delete掉。
三、RefBase
RefBase提供了更强大的引用计数的管理。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
|
class RefBase { public : void incStrong( const void *
id) const ; void decStrong( const void *
id) const ; void forceIncStrong( const void *
id) const ; //!
DEBUGGING ONLY: Get current strong ref count. int32_t
getStrongCount() const ; class weakref_type { public : RefBase
refBase() const ; void incWeak( const void *
id); void decWeak( const void *
id); //
acquires a strong reference if there is already one. bool attemptIncStrong( const void *
id); //
acquires a weak reference if there is already one. //
This is not always safe. see ProcessState.cpp and BpBinder.cpp //
for proper use. bool attemptIncWeak( const void *
id); //!
DEBUGGING ONLY: Get current weak ref count. int32_t
getWeakCount() const ; //!
DEBUGGING ONLY: Print references held on object. void printRefs() const ; //!
DEBUGGING ONLY: Enable tracking for this object. //
enable -- enable/disable tracking //
retain -- when tracking is enable, if true, then we save a stack trace //
for each reference and dereference; when retain == false, we //
match up references and dereferences and keep only the //
outstanding ones. void trackMe( bool enable, bool retain); }; weakref_type*
createWeak( const void *
id) const ; weakref_type*
getWeakRefs() const ; //
DEBUGGING ONLY: Print references held on object. inline void printRefs() const {
getWeakRefs()->printRefs(); } //
DEBUGGING ONLY: Enable tracking of object. inline void trackMe( bool enable, bool retain) { getWeakRefs()->trackMe(enable,
retain); } typedef RefBase
basetype; protected : RefBase(); virtual ~RefBase(); //!
Flags for extendObjectLifetime() enum { OBJECT_LIFETIME_STRONG
= 0x0000, OBJECT_LIFETIME_WEAK
= 0x0001, OBJECT_LIFETIME_MASK
= 0x0003 }; void extendObjectLifetime(int32_t
mode); //!
Flags for onIncStrongAttempted() enum { FIRST_INC_STRONG
= 0x0001 }; virtual void onFirstRef(); virtual void onLastStrongRef( const void *
id); virtual bool onIncStrongAttempted(uint32_t
flags, const void *
id); virtual void onLastWeakRef( const void *
id); private : friend class weakref_type; class weakref_impl; RefBase( const RefBase&
o); RefBase&
operator=( const RefBase&
o); weakref_impl* const mRefs; }; |
不同于LightRefBase的是,RefBase内部并没有使用一个变量来维护引用计数,而是通过一个weakref_impl *类型的成员来维护引用计数,并且同时提供了强引用计数和弱引用计数。weakref_impl继承于RefBase::weakref_type,代码比较多,不过大都是调试代码,由宏定义分开,Release是不包含调试代码的,去除这些代码后其定义为:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
#define
INITIAL_STRONG_VALUE (1<<28) class RefBase::weakref_impl
: public RefBase::weakref_type { public : volatile int32_t
mStrong; volatile int32_t
mWeak; RefBase* const mBase; volatile int32_t
mFlags; weakref_impl(RefBase*
base) :
mStrong(INITIAL_STRONG_VALUE) ,
mWeak(0) ,
mBase(base) ,
mFlags(0) { } void addStrongRef( const void * /*id*/ )
{ } void removeStrongRef( const void * /*id*/ )
{ } void addWeakRef( const void * /*id*/ )
{ } void removeWeakRef( const void * /*id*/ )
{ } void printRefs() const {
} void trackMe( bool , bool )
{ } }; |
weakref_impl中的函数都是作为调试用,Release版的实现都是空的,成员变量分别表示强引用数、弱引用数、指向实际对象的指针与flag,flag可控制实际对象的生命周期,取值为0或RefBase中定义的枚举值。
RefBase提供了incStrong与decStrong函数用于控制强引用计数值,其弱引用计数值是由weakref_impl控制,强引用计数与弱引用数都保存在weakref_impl *类型的成员变量mRefs中。
RefBase同LightRefBase一样为对象提供了引用计数的方法,对引用计数的管理同样要由智能指针控制,由于RefBase同时实现了强引用计数与弱引用计数,所以就有两种类型的智能指针,sp(Strong Pointer)与wp(Weak Pointer)。
sp前面已经说过,其(拷贝)构造函数调用对象即RefBase的incStrong函数。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
void RefBase::incStrong( const void *
id) const { weakref_impl* const refs
= mRefs; refs->incWeak(id); refs->addStrongRef(id); const int32_t
c = android_atomic_inc(&refs->mStrong); LOG_ASSERT(c
> 0, "incStrong()
called on %p after last strong ref" ,
refs); if (c
!= INITIAL_STRONG_VALUE) { return ; } android_atomic_add(-INITIAL_STRONG_VALUE,
&refs->mStrong); refs->mBase->onFirstRef(); } |
addStrong的函数体为空,incStrong函数内部首先调用成员变量mRefs的incWeak函数将弱引用数加1,然后再将强引用数加1,由于android_atomic_inc返回变量的旧值,所以如果其不等于INITIAL_STRONG_VALUE就直接返回,则则是第一次由强智能指针(sp)引用,将其减去INITIAL_STRONG_VALUE后变成1,然后调用对象的onFirstRef。
成员变量mRefs是在对象的构造函数中初始化的:
1
2
3
4
|
RefBase::RefBase() :
mRefs( new weakref_impl( this )) { } |
weakrel_impl的incWeak继承自父类weakrel_type的incWeak:
1
2
3
4
5
6
7
|
void RefBase::weakref_type::incWeak( const void *
id) { weakref_impl* const impl
= static_cast <weakref_impl*> impl->addWeakRef(id); const int32_t
c = android_atomic_inc(&impl->mWeak); LOG_ASSERT(c
>= 0, "incWeak
called on %p after last weak ref" , this ); } |
addWeakRef实现同样为空,所以只是将弱引用计数加1。所以当对象被sp引用后,强引用计数与弱引用计数会同时加1。
当sp销毁时其析构函数调用对象即RefBase的decStrong函数:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
void RefBase::decStrong( const void *
id) const { weakref_impl* const refs
= mRefs; refs->removeStrongRef(id); const int32_t
c = android_atomic_dec(&refs->mStrong); if (c
== 1) { const_cast <RefBase*>( this )->onLastStrongRef(id); if ((refs->mFlags&OBJECT_LIFETIME_WEAK)
!= OBJECT_LIFETIME_WEAK) { delete this ; } } refs->removeWeakRef(id); refs->decWeak(id); } |
decStrong中将强引用数与弱引用数同时减1,如果这是最后一个强引用的话,会调用对象的onLastStrongRef,并且判断成员变量mRefs的成员变量mFlags来决定是否在对象的强引用数为0时释放对象。
mFlags可以为0或以下两个枚举值:
1
2
3
4
|
enum { OBJECT_LIFETIME_WEAK
= 0x0001, OBJECT_LIFETIME_FOREVER
= 0x0003 }; |
mFlags的值可以通过extendObjectLifetime函数改变:
1
2
3
4
|
void RefBase::extendObjectLifetime(int32_t
mode) { android_atomic_or(mode,
&mRefs->mFlags); } |
OBJECT_LIFETIME_FOREVER包含OBJECT_LIFETIME_WEAK(位运算中其二进制11包含01),所以当
1
|
refs->mFlags&OBJECT_LIFETIME_WEAK)
!= OBJECT_LIFETIME_WEAK |
为true时表示mFlags为0,实际对象的生命周期受强引用数控制,所以在强引用数为0时delete this,否则实际对象的生命周期就由弱引用数控制。
再来看decWeak:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
void RefBase::weakref_type::decWeak( const void *
id) { weakref_impl* const impl
= static_cast <weakref_impl*>( this ); impl->removeWeakRef(id); const int32_t
c = android_atomic_dec(&impl->mWeak); if (c
!= 1) return ; if ((impl->mFlags&OBJECT_LIFETIME_WEAK)
!= OBJECT_LIFETIME_WEAK) { if (impl->mStrong
== INITIAL_STRONG_VALUE) delete impl->mBase; else { delete impl; } } else { impl->mBase->onLastWeakRef(id); if ((impl->mFlags&OBJECT_LIFETIME_FOREVER)
!= OBJECT_LIFETIME_FOREVER) { delete impl->mBase; } } } |
将弱引用数减1,若减1后不为0直接返回,否则判断
1
|
(impl->mFlags&OBJECT_LIFETIME_WEAK)
!= OBJECT_LIFETIME_WEAK |
-
判断结果为true:
-
实际对象生命周期被强引用数控制,接下来判断:
1
|
mpl->mStrong
== INITIAL_STRONG_VALUE |
-
如果判断为true表示对象只被弱引用引用过,现在弱引用数为0,直接删除实际对象。
-
如果判断为false,表示对象曾经被强引用引用过,但现在强引用为变为0了(因为增加或减小强引用数时一定同时增加或减小弱引用数,所以弱引用数为0时,强引用数一定为0),弱引用数为0了,直接释放mRefs,而实际对象由于受强引用数控制,已经在RefBase::decStrong中被delete了。
-
-
判断结果为false:
判断mFlgs是否是OBJECT_LIFETIME_FOREVER,如果是,什么都不作由用户自己控制对象的生命周期,否则,实际对象的生命周期受弱引用数控制,现在弱引用数为0,delete实际对象。
四、wp(Weak Pointer)
定义如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
|
template < typename T> class wp { public : typedef typename RefBase::weakref_type
weakref_type; inline wp()
: m_ptr(0) { } wp(T*
other); wp( const wp<T>&
other); wp( const sp<T>&
other); template < typename U>
wp(U* other); template < typename U>
wp( const sp<U>&
other); template < typename U>
wp( const wp<U>&
other); ~wp(); //
Assignment wp&
operator = (T* other); wp&
operator = ( const wp<T>&
other); wp&
operator = ( const sp<T>&
other); template < typename U>
wp& operator = (U* other); template < typename U>
wp& operator = ( const wp<U>&
other); template < typename U>
wp& operator = ( const sp<U>&
other); void set_object_and_refs(T*
other, weakref_type* refs); //
promotion to sp sp<T>
promote() const ; //
Reset void clear(); //
Accessors inline weakref_type*
get_refs() const { return m_refs;
} inline T*
unsafe_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; T*
m_ptr; weakref_type*
m_refs; }; |
同sp一样,m_ptr指向实际对象,但wp还有一个成员变量m_refs。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
template < typename T> wp<T>::wp(T*
other) :
m_ptr(other) { if (other)
m_refs = other->createWeak( this ); } template < typename T> wp<T>::wp( const wp<T>&
other) :
m_ptr(other.m_ptr), m_refs(other.m_refs) { if (m_ptr)
m_refs->incWeak( this ); } RefBase::weakref_type*
RefBase::createWeak( const void *
id) const { mRefs->incWeak(id); return mRefs; } |
可以看到,wp的m_refs就是RefBase即实际对象的mRefs。
wp析构的时候减少弱引用计数:
1
2
3
4
5
|
template < typename T> wp<T>::~wp() { if (m_ptr)
m_refs->decWeak( this ); } |
由于弱指针没有重载*与->操作符,所以不能直接操作指向的对象,虽然有unsafe_get函数,但像名字所示的,不建议使用,直接使用实际对象指针的话就没必要用智能指针了。
因为弱指针不能直接操作对象,所以要想操作对象的话就要将其转换为强指针,即wp::promote方法:
1
2
3
4
5
6
7
8
9
10
11
|
template < typename T> sp<T>
wp<T>::promote() const { return sp<T>(m_ptr,
m_refs); } template < typename T> sp<T>::sp(T*
p, weakref_type* refs) :
m_ptr((p && refs->attemptIncStrong( this ))
? p : 0) { } |
是否能从弱指针生成一个强指针关键是看refs->attemptIncStrong,看其定义:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
|
bool RefBase::weakref_type::attemptIncStrong( const void *
id) { incWeak(id); weakref_impl* const impl
= static_cast <weakref_impl*>( this ); int32_t
curCount = impl->mStrong; LOG_ASSERT(curCount
>= 0, "attemptIncStrong
called on %p after underflow" , this ); while (curCount
> 0 && curCount != INITIAL_STRONG_VALUE) { if (android_atomic_cmpxchg(curCount,
curCount+1, &impl->mStrong) == 0) { break ; } curCount
= impl->mStrong; } if (curCount
<= 0 || curCount == INITIAL_STRONG_VALUE) { bool allow; if (curCount
== INITIAL_STRONG_VALUE) { //
Attempting to acquire first strong reference... this is allowed //
if the object does NOT have a longer lifetime (meaning the //
implementation doesn't need to see this), or if the implementation //
allows it to happen. allow
= (impl->mFlags&OBJECT_LIFETIME_WEAK) != OBJECT_LIFETIME_WEAK ||
impl->mBase->onIncStrongAttempted(FIRST_INC_STRONG, id); } else { //
Attempting to revive the object... this is allowed //
if the object DOES have a longer lifetime (so we can safely //
call the object with only a weak ref) and the implementation //
allows it to happen. allow
= (impl->mFlags&OBJECT_LIFETIME_WEAK) == OBJECT_LIFETIME_WEAK &&
impl->mBase->onIncStrongAttempted(FIRST_INC_STRONG, id); } if (!allow)
{ decWeak(id); return false ; } curCount
= android_atomic_inc(&impl->mStrong); //
If the strong reference count has already been incremented by //
someone else, the implementor of onIncStrongAttempted() is holding //
an unneeded reference. So call onLastStrongRef() here to remove it. //
(No, this is not pretty.) Note that we MUST NOT do this if we //
are in fact acquiring the first reference. if (curCount
> 0 && curCount < INITIAL_STRONG_VALUE) { impl->mBase->onLastStrongRef(id); } } impl->addWeakRef(id); impl->addStrongRef(id); #if
PRINT_REFS LOGD( "attemptIncStrong
of %p from %p: cnt=%d\n" , this ,
id, curCount); #endif if (curCount
== INITIAL_STRONG_VALUE) { android_atomic_add(-INITIAL_STRONG_VALUE,
&impl->mStrong); impl->mBase->onFirstRef(); } return true ; } |
首先通过incWeak将弱引用数加1(被强指针sp引用会导致强引用数和弱引用数同时加1),然后:
1
2
3
4
5
6
7
|
int32_t
curCount = impl->mStrong; while (curCount
> 0 && curCount != INITIAL_STRONG_VALUE) { if (android_atomic_cmpxchg(curCount,
curCount+1, &impl->mStrong) == 0) { break ; } curCount
= impl->mStrong; } |
如果之前已经有强引用,直接将强引用数加1,android_atomic_cmpxchg表示如果impl->mStrong的值为curCount,则把impl->mString的值改为curCount+1,此处用while循环是防止其他线程已经增加了强引用数。
接下来:
1
|
if (curCount
<= 0 || curCount == INITIAL_STRONG_VALUE) |
表示对象目前没有强引用,这就要判断对象是否存在了。
如果curCount == INITIAL_STRONG_VALUE,表示对象没有被sp引用过。接下来判断:
1
2
|
allow
= (impl->mFlags&OBJECT_LIFETIME_WEAK) != OBJECT_LIFETIME_WEAK ||
impl->mBase->onIncStrongAttempted(FIRST_INC_STRONG, id); |
表示:如果对象的生命周期只受强引用控制,对象一定存在,要有强引用才可以管理对象的释放,所以一定会允许生成强引用;如果对象的生命周期受弱引用控制,调用对象的onIncStrongAttempted试图增加强引用,由于此时在弱引用中,弱引用一定不为0,对象也一定存在,调用onIncStrongAttempted的意图是因为类的实现者可能不希望用强引用引用对象。在RefBase中onIncStrongAttempted默认返回true:
1
2
3
4
|
bool RefBase::onIncStrongAttempted(uint32_t
flags, const void *
id) { return (flags&FIRST_INC_STRONG)
? true : false ; } |
如果curCount <= 0(只会等于0),表示对象强引用数经历了INITIAL_STRONG_VALUE -->大于0 --> 0,接下来就要判断:
1
2
|
allow
= (impl->mFlags&OBJECT_LIFETIME_WEAK) == OBJECT_LIFETIME_WEAK &&
impl->mBase->onIncStrongAttempted(FIRST_INC_STRONG, id); |
如果对象的生命周期受强引用数控制,那么由于曾被sp引用过,现在强引用数又为0,对象就已经被delete了,所以就不能生成强引用,否则如果对象的生命周期受弱引用数控制,就通过onIncStrongAttempted看类的实现者是否希望当对象的强引用数变为0时可以再次被强引用引用。
1
2
3
4
|
if (!allow)
{ decWeak(id); return false ; } |
如果allow为false表示不能从弱引用生成强引用,就要调用decWeak将弱引用减1(因为在promote入口先将弱引用加了1),然后返回false表示生成强引用失败。
1
2
3
4
|
if (curCount
== INITIAL_STRONG_VALUE) { android_atomic_add(-INITIAL_STRONG_VALUE,
&impl->mStrong); impl->mBase->onFirstRef(); } |
最后,如果curCount == INITIAL_STRONG_VALUE表示第一次被sp引用,调用对象的onFirstRef函数。
五、总结
RefBase内部有一个指针指向实际对象,有一个weakref_impl类型的指针保存对象的强/弱引用计数、对象生命周期控制。
sp只有一个成员变量,用来保存实际对象,但这个实际对象内部已包含了weakref_impl *对象用于保存实际对象的引用计数。sp 管理一个对象指针时,对象的强、弱引用数同时加1,sp销毁时,对象的强、弱引用数同时减1。
wp中有两个成员变量,一个保存实际对象,另一个是weakref_impl *对象。wp管理一个对象指针时,对象的弱引用计数加1,wp销毁时,对象的弱引用计数减1。
weakref_impl中包含一个flag用于决定对象的生命周期是由强引用数控制还是由弱引用数控制:
-
当flag为0时,实际对象的生命周期由强引用数控制,weakref_impl *对象由弱引用数控制。
-
当flag为OBJECT_LIFETIME_WEAK时,实际对象的生命周期受弱引用数控制。
-
当flag为OBJECT_LIFETIME_FOREVER时,实际对象的生命周期由用户控制。
可以用extendObjectLifetime改变flag的值。