深入FDO 記憶體管理機制

2021-05-10 19:28:39 字數 2339 閱讀 9184

呼叫某些fdo的函式,如建立方法,需要申請記憶體,而這些記憶體需要在適當的時機釋放,以免記憶體洩漏。fdo使用了引用計數的方式來實現管理物件的生命週期,每個物件都維護著乙個引用計數,只有當這個物件的引用計數變為0時,才會去釋放這個物件。所以,fdo中每個類都從fdoidisposable類繼承而來的,fdoidisposable定義了release()和addref()方法。呼叫方法release()會將當前物件的引用計數減1,然後判斷這個物件的引用計數是否變為0了,如果是則釋放這個物件;呼叫方法addref()會將當前物件的引用計數加1。為了防止用於呼叫操作符delete釋放乙個物件,fdo中所有類的析構函式都是protected的,呼叫者只能通過呼叫release()方法來釋放物件。

為了簡化物件的建立和釋放,fdo預定義了如下兩個巨集。

1.

fdo_safe_release (*ptr)

如果「*ptr」不是空指標,fdo_safe_release就會呼叫「*ptr」 所指物件的release()方法,而後把指向該物件的指標賦為null。該巨集定義的實現為:

#define fdo_safe_release(x)

該巨集的使用方式如下所示。

fdofeatureclass* pbase = myclass->getbaseclass();

...fdo_safe_release(pbase);

2.

fdo_safe_addref (*ptr)

如果「*ptr」不是空指標,fdo_safe_addref就會呼叫「*ptr」所指物件的addref()方法。該巨集定義的實現為:

#define fdo_safe_addref(x) ((x != null) ? (x)->addref(), (x): (null))

例如當執行**fdo_safe_addref(value)時,如果value是null那麼返回值也是null,否則把value所指物件的引用計數加一併返回value。

fdoptr

是用來協助記憶體管理的智慧型指標,它是乙個c++模板類,它模板引數必須繼承自fdoidisposable的類。使用者可以把fdo物件用該指標加以封裝,這樣,物件就可以在fdoptr出作用域時自動釋放。以下是使用fdoptr的乙個例子:

fdoptrpbase = myclass->getbaseclass();

...上面的**無需呼叫fdo_safe_release,在fdoptr銷毀之前,pbase會呼叫fdofeatureclass 物件的release()方法。

如果由於某些原因我們想對fdoptr呼叫fdo_safe_release,我們必須得到fdoptr封裝的指向物件的指標,然後把該指標傳入fdo_safe_release。使用者可以把fdoptr用於自定義的類,當然這些類需要繼承自fdoidisposable,並且要實現dispose()方法。

如果你把呼叫fdo方法返回的指標賦給了乙個非智慧型指標,那麼你應該把這個非智慧型指標再賦值給乙個fdoptr,例如:

fdolinestring* p = gf.createlinestring(...);

fdoptr p2 = fdo_safe_addref(p);

智慧型指標為記憶體管理帶來很大的便利,但是如果使用不當反而會產生一些問題,乙個比較常見的問題就是鏈式呼叫,鏈式呼叫會導致返回的指標無法釋放。假設

pclassdef

是指向類

fdoclassdefinition

例項的乙個指標,那麼如下的**會導致兩處記憶體洩露。

psz = pclassdef ->getproperties()->getitem(0)->getname());

正確的用法為:

fdopropertydefinitioncollection* pprops = pclassdef -> getproperties();

fdopropertydefinition* ppropdef = pprops->getitem(0);

psz = propdef->getname();

ppropdef->release();

pprops->release();或者(

使用fdoptr)

fdoptrpprops = pclassdef-> getproperties();

fdoptrppropdef = pprops-> getitem(0);

psz = propdef->getname();或者(

還是使用

fdoptr)

psz = fdoptr (fdoptr

(pclassdef->getproperties())-> getitem(0))->getname();

記憶體管理機制

記憶體管理 jvm將記憶體分成三大主要區域 堆,棧,方法區,用來儲存資料。堆 堆中主要儲存引用型別物件,給成員變數分配空間。棧 jvm在執行程式時,在棧中會為每乙個方法都提供儲存空間叫棧幀,用來儲存方法中的區域性變數。方法區 用來儲存jvm載入的位元組碼檔案的資訊 類的資訊 包含類的方法,方法只有乙...

記憶體管理機制

記憶體管理是乙個作業系統必不可少 並且 非常重要的一環 linux 的成功 和它優秀的記憶體管理聯絡非常密切 因為乙個系統的高效性慾穩定性往往決定於它的記憶體管理機制 我項很多人吃過 dos 下 640k 的苦吧 前面我們介紹了 386 保護模式 從今天起我們將在此基礎上 分析 linux 的虛擬儲...

iOS 記憶體管理機制

學習要點 1.reference counting 引用計數機制 2.了解mrc apc和gc 3.autoreleasepool 執行機制 4.如何避免 retain cycle reference counting 引用計數機制 cocoa 上基本的記憶體管理機制就是引用計數,通過乙個 refe...