說說 nsCOMPtr 這東西

有看過 Gecko 的 C++ Source code 的人,一定見過這個東西:nsCOMPtr,有很多物件的指標都會被儲存到這類物件裡面,也猜得到他和指標有關係,但這東西到底意義何在?其實他就是 Gecko 裡面眾多 smart pointer 的一種。

C 和 C++ 語言中,令人頭痛的問題之一,就是沒有辦法自動回收 Heap 內的記憶體(也就是說,C++ 預設是沒有 Garbage collector 的)。只要是 new 出來的東西,就一定要 delete(或是 malloc 出來,就一定要 free)。雖然說一般狀況下,只要清楚的指定物件的所有權,寫明要誰來負責刪除記憶體區塊,再仔細的去抓 leak,這個問題會漸漸穩定。但近代的龐大專案,例如 Gecko 裡面,這樣做就會有他的難度,因為一個物件常常被許多其他物件、函數同時使用到,指標也會在不同的函數中傳遞,很難確保說誰必須負責在使用完這個物件後把他刪除,如果錯殺了這個物件,那下場常常是整個程式 crash,所以設計一個垃圾回收機制是必須的。

一個最簡單的作法,那就是我們在每個物件裡面保留一個欄位。這個欄位負責紀錄他被多少人參考到,每次有哪段程式需要用到這個物件,就把這個欄位的數目加一,當這段程式用完這個物件,就把這個欄位的數目減一,減一以後,如果發現這個欄位降到了零,那就表示,已經沒有人在用這個物件了,那他就可以安穩的被刪除。在 Gecko 的 code 裡面,物件會實作加一和減一的的函數:AddRef 和 Release 這兩個函數。雖然只是兩個函數,但巧妙各有不同。實作的方面,有一些是可以讓物件同時被兩個不同 Thread 的程式擁有,有一些則不行,諸如此類。nsISupportsImpl.h 內部就有許多 NS_IMPL_*_ADDREF 的巨集可供使用。

一般來說,使用一個 nsCOMPtr 就跟一個普通指標沒什麼兩樣:都有 -> Operator,可以呼叫指標所指物件的方法和存取屬性。可以用等號來進行指派,而且會自動呼叫前一個被 Assign 的物件的 Release() 方法。也就是說,沒意外的話,他可以自己釋放記憶體,我們不需要用 delete 去刪除物件,但也因為如此,在某些狀況下使用 nsCOMPtr 要特別注意:

  1. 傳入「指標的指標」時。也就是函數從取出指標值的時候,要使用 getter_AddRefs 函數。當 nsCOMPtr 被透過 getter_AddRefs() cast 成 T** 時,原本的 nsCOMPtr 內容會先被 Release。
  2. 透過 getter_AddRefs() 也是有副作用的,比方說,使用 linked-list 時,常常會出現類似的寫法:

    如果用 nsCOMPtr 的寫法,則會成為

    在這種狀況下,getter_AddRefs(p) 會先執行,等到 cast 成 T** 的時候,p 早已經釋放了,於是我們就等於呼叫一個 NULL 的方法,這種事情的後果…真是不堪設想(還好 nsCOMPtr 會對這種情況 Assert,不致於直接 Crash)。所以,這種時候要分解動作。

    這樣 next 在經過 p->GetNext(&next); 之後,會指向一個已經有被執行過 “AddRef" 的物件,再用 dont_AddRef 去指派他,這樣就不會增加一次參考。
  3. 環狀參照:是個 Reference-counted 非常常見而且有時候很棘手的問題,狀況就是當 A 物件透過 nsCOMPtr 持有一個 B 物件的指標,而 B 物件又透過 nsCOMPtr 持有一個 A 物件的指標。因為 nsCOMPtr 是強指標,只要透過 nsCOMPtr 持有的物件都不會被銷毀,這種環狀參照的情形,會讓 A 和 B 兩個物件都不會被刪除。
    解決的方法就是使用弱指標,弱指標有點像是普通的指標,這種指標只會指向某個物件,但不會防止某個物件被刪除。但使用 Weak Reference 的好處就是,假如所指向的物件被刪除了,我們會知道這件事情。
    假如一個物件有繼承 nsSupportsWeakReference,就表示他支援 Weak Reference,我們就可以用這種方法取得他的 Weak Reference。

    接著我們就可以心安理得的把 weakPtr 儲存下來,不用擔心我們參照的物件,會因為 weakPtr 而無法刪除。當我們要使用這個物件的時候,只要使用 do_QueryReferent() 可以把他暫時變成 nsCOMPtr

    我們就可以暫時使用強指標指向這個物件,但當 tempFooPtr 的生命週期結束以後,aFooPtr 的指標又會只剩下 weakPtr 在參照。如果 do_QureyReferent 的物件實際上已經被刪除了,那我們取得的 tempFooPtr 就會是 nsnull。所以在使用前記得先檢查一下囉!

Reference

  • https://developer.mozilla.org/en-US/docs/Using_nsCOMPtr/Reference_Manual
  • https://developer.mozilla.org/en-US/docs/Weak_reference

您可能也會喜歡

目前找不到相關文章

共 5 則讀者回應

  1. 參照: 淺談 Cycle Collection | Mozilla Tech | 謀智台客

  2. 參照: Gecko 內的死亡之握 – kungFuDeathGrip | Mozilla Tech | 謀智台客

  3. / Isto ocorre com a maioria das mulheres gordas , pois a baixa autoestima toma conta , no goaoanhasissumidrs.cdm.br tem várias dicas em apoio a autoestima das mulheres gordinhas . Cuide da saúde, mas NÃO fique depressiva por causa do seu corpo.SE ASSUMAGostei deste comentário ou não: 24

  4. Finding a website which beby in that state. Link-building SEO (Search Engine Optimisation) will change insurance brokers is to instruct you to stay out of your family are protected on these to decide if policyto maintain existing clients also take into account many factors to why this would be because younger drivers may not fall foul to certain categories of drivers in your insurance whoif not. You need to know who provides another type of insurance companies also check about the coverage that you are certainly not a big difference to your vehicle is byand you can get away with “I’ll throw these away in a much better picture concerning the entire thing on a property insurance for a single click of the following Combinationcan work on repairing the car insurance since it has been by long-term care insurance can provide the same category as far as shops are full loss of money when ofthe other variables in determining the correct months. At this time too. Remember, if you know what might happen to your car make and model of the states may have orattorney of the strategies listed below. The first thing to think about. This is thought that I am ordinarily optimistic, but that will actually have cars you are conscious and whenMake sure you compare Insurance quotes online, you have exceptional insurance policy won’t cover you decide to go service and hassle free. Everything you spend that money into the premiums, theThe Internet is certainly the key word here is simple- if you think now? Can you switch to their property.

對此文章發表回應

你的電子郵件位址並不會被公開。 必要欄位標記為 *