如何解決OSG記憶體管理問題?

2021-09-28 20:05:42 字數 2167 閱讀 7175

osg是使用c++語言開發的,而該語言在動態記憶體管理方面做得並不好,經常需要程式設計師手動申請和釋放記憶體。這種靠人工管理記憶體的方式不僅繁瑣,而且極易造成記憶體洩漏,尤其在乙個中大型系統中,靠人工管理記憶體是一項艱鉅的任務。

資料型別osg::ref_ptr(智慧型指標)在原始碼中隨處可見,它和另外一種資料型別osg::observer_ptr(觀察指標)為我們提供了非常良好的動態物件使用體驗。

智慧型指標的用法

osg::node* pnode = new osg::node();

osg::ref_ptr< osg::node>rpnode=pnode;

if(rpnode.valid())

通過osg::node例項化乙個智慧型指標模板物件rpnode,該物件可以直接儲存乙個使用new關鍵字動態建立的osg::node物件,並可通過valid() 方法判斷內部物件是否有效。

使用->操作符直接對內部物件進行呼叫,這裡無需關心osg::node物件的釋放,因為在智慧型指標物件rpnode析構時會自動檢查是否需要刪除物件,如果需要則直接刪除。

觀察指標的用法

osg::node* pnode = new osg::node();

osg::observer_ptr< osg::node>opnode=pnode;

if(opnode.valid())

osg::observer_ptr與osg::ref_ptr的用法基本相同,不同的是osg::observer_ptr不負責物件的釋放,這也是為什麼叫它觀察指標的原因,可理解為只觀察不管理。

所以,上面**如果沒有其他osg::ref_ptr智慧型指針對建立的osg::node物件進行管理,將造成記憶體洩漏,該物件將不會自動釋放。

實現原理

osg::ref_ptr和osg::observer_ptr是兩個模板類,而用於例項化該模板類的型別必須從osg::referenced繼承。osg中大多數型別都是從該類繼承而來的,它才是實現記憶體自動管理的核心所在。

osg::referenced類最主要的功能是內部維護了乙個引用計數_refcount,並提供了ref()和unref()函式來負責該引用計數的遞增和遞減。在unref()函式中,當_refcount遞減為0值時會自動釋放該物件占用的記憶體。

有了osg::referenced類的支援,對於osg::ref_ptr而言其實只需要做兩件事:

1)在著手管理乙個物件時呼叫該物件的ref()方法增加其引用計數;

2)當不在管理該物件時呼叫該物件的unref()方法減少其引用計數。

osg::observer_ptr的實現正如它的名字一樣,是通過一種簡單的「觀察者」設計模式來實現的。osg::referenced內部維護了乙個觀察者列表,並且在引用計數遞減為0時主動通知所有的觀察者物件,每乙個osg::observer_ptr物件都是乙個觀察者。

對於osg:: observer _ptr而言需要做以下三件事:

1)在開始觀察乙個物件時將自己加入到該物件的觀察者列表中;

2)在停止觀察物件時將自己從該物件的觀察者列表中移除;

3)收到觀察者通知時,將內部觀察的物件設定為無效。

關係如下

通過下表,我們來體會一下osg中物件的建立和釋放的過程,以及在這當中智慧型指標與觀察指標的作用,引用計數的變化情況等。

每乙個osg::ref_ptr物件都占有乙個被引用物件的引用計數,在正常情況下只要最後乙個osg::ref_ptr還在使用,被它引用的物件就不會釋放。所以osg::ref_ptr可用於需要長期使用並保證乙個物件可用的情況。

osg::observer_ptr 作為物件的觀察者,最大的作用就是可以在訪問其觀察的物件時,判斷該物件是否已經被銷毀了。它只是嘗試性的使用,不對觀察物件產生任何影響,觀察的物件隨時可能被釋放,所以應該經常使用valid()方法判斷其有效性。

通過以上介紹,相信大家對osg的智慧型指標和觀察指標都有了一定程度的理解,並且可以在不同場景下做到正確使用。

如何解決藍屏問題

第一步 公升級筆記本bios 一般說來筆記本在出廠的時候很可能設計上存在某些的瑕疵,而廠商通常會採用公升級bios的方法來解決這些bug。如果我們在使用筆記本腦的過程中遇到了藍屏的情況,那麼我們可以採取公升級bios的辦法來解決藍屏的故障。第二步 正確安裝硬體驅動 在重新整理了bios以後,部分筆記...

如何解決fpga high fanout問題

fanout,即扇出,指模組直接呼叫的下級模組的個數,如果這個數值過大的話,在fpga直接表現為net delay較大,不利於時序收斂。因此,在寫 時應盡量避免高扇出的情況。但是,在某些特殊情況下,受到整體結構設計的需要或者無法修改 的限制,則需要通過其它優化手段解決高扇出帶來的問題。以下就介紹三個...

如何解決fpga high fanout問題

fanout,即扇出,指模組直接呼叫的下級模組的個數,如果這個數值過大的話,在fpga直接表現為net delay較大,不利於時序收斂。因此,在寫 時應盡量避免高扇出的情況。但是,在某些特殊情況下,受到整體結構設計的需要或者無法修改 的限制,則需要通過其它優化手段解決高扇出帶來的問題。以下就介紹三個...