亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

為什么C ++沒有垃圾回收器?

為什么C ++沒有垃圾回收器?

C++
Smart貓小萌 2019-12-07 14:28:34
首先,因為垃圾收集的優點,所以我沒有問這個問題。我提出這個問題的主要原因是,我確實知道Bjarne Stroustrup曾說過C ++將在某個時間點具有垃圾回收器。話雖如此,為什么不添加呢?已經有一些C ++的垃圾收集器。這只是那些“說起來容易做起來難”的事情之一嗎?還是有其他原因沒有被添加(并且不會在C ++ 11中添加)?交叉鏈接:C ++垃圾收集器為了澄清起見,我理解C ++首次創建時沒有垃圾收集器的原因。我想知道為什么不能添加收集器。
查看完整描述

3 回答

?
慕容森

TA貢獻1853條經驗 獲得超18個贊

可以添加隱式垃圾回收,但是并沒有成功??赡懿粌H是由于實施方面的復雜性,還因為人們沒有足夠快地達成普遍共識。


Bjarne Stroustrup自己的話:


我曾希望可以選擇啟用的垃圾收集器將成為C ++ 0x的一部分,但是我有足夠的技術問題需要解決,只需詳細說明這種收集器如何與語言的其余部分集成即可。 (如果提供)。與基本上所有C ++ 0x功能的情況一樣,存在實驗性實現。


有話題商量好了這里。


總體概述:


C ++功能非常強大,幾乎可以做任何事情。因此,它不會自動將很多可能影響性能的事情推到您身上。垃圾回收可以通過智能指針輕松實現(智能對象包裝帶有引用計數的指針,當引用計數達到0時,這些對象會自動刪除自身)。


C ++是在沒有垃圾收集的情況下考慮競爭對手而構建的。與C和其他語言相比,效率是C ++必須抵制批評的主要問題。


垃圾收集有2種類型...


顯式垃圾回收:


C ++ 0x將通過使用shared_ptr創建的指針進行垃圾回收


如果您想要它,則可以使用它;如果您不想要它,則不會被迫使用它。


如果您不想等待C ++ 0x,則當前還可以使用boost:shared_ptr。


隱式垃圾回收:


它沒有透明的垃圾收集器。不過,它將成為未來C ++規范的重點。


為什么Tr1沒有隱式垃圾回收?


C ++ 0x的tr1應該有很多東西,Bjarne Stroustrup在之前的采訪中指出,tr1沒有他想要的東西。


查看完整回答
反對 回復 2019-12-07
?
慕后森

TA貢獻1802條經驗 獲得超5個贊

在這里增加辯論。


垃圾回收存在一些已知問題,對它們的了解有助于理解C ++中為什么沒有垃圾回收的問題。


1.性能


第一個抱怨通常是關于性能的,但是大多數人并沒有真正意識到他們在說什么。如圖所示,Martin Beckett問題可能不是性能本身,而是性能的可預測性。


當前有2個廣泛使用的GC系列:


標記和掃描種類

參考計數種類

該Mark And Sweep快(對整體性能的影響較小),但它從一個“凍結世界”綜合癥患有:即當在GC踢,一切停止,直到GC作出了清理。如果您希望構建可以在幾毫秒內響應的服務器...某些事務將無法達到您的期望:)


問題Reference Counting不同:引用計數會增加開銷,尤其是在多線程環境中,因為您需要具有原子計數。此外,還有參考循環的問題,因此您需要一個聰明的算法來檢測這些循環并消除它們(通常也通過“凍結世界”來實現,盡管頻率較低)??傮w而言,截至今天,這種方法(即使通常響應速度更快或更不頻繁地凍結)也比慢Mark And Sweep。


我看過埃菲爾鐵塔實施者的論文,他們試圖實施一個Reference Counting垃圾收集器,該垃圾收集器的全球性能與Mark And Sweep沒有“凍結世界”方面的相似。它需要用于GC的單獨線程(典型)。該算法有點令人恐懼(最后),但是論文很好地完成了一次介紹一個概念并展示了算法從“簡單”版本到成熟版本的演變。推薦閱讀,只要我能把雙手放回PDF文件上即可...


2.資源獲取正在初始化(RAII)


這是一個常見的習慣用法C++,您將資源的所有權包裝在一個對象中以確保正確釋放它們。因為我們沒有垃圾回收,所以它主要用于內存,但是它在許多其他情況下也很有用:


鎖(多線程,文件句柄等)

連接(到數據庫,另一臺服務器...)

這個想法是適當地控制對象的生存期:


只要你需要它就應該還活著

完成后應將其殺死

GC的問題是,如果它對前者有所幫助并最終保證在以后……“最終”可能還不夠。如果您釋放鎖,那么您真的希望它現在被釋放,這樣它就不會阻止任何進一步的呼叫!


使用GC的語言有兩種解決方法:


當堆棧分配足夠時不要使用GC:通常是為了解決性能問題,但是在我們的情況下,這確實有用,因為范圍定義了生命周期

using構造...但是它是顯式的(弱)RAII,而在C ++中,RAII是隱式的,因此用戶不能不經意間犯錯誤(通過省略using關鍵字)

3.智能指針


智能指針通常表現為處理內存中的銀彈C++。我經常聽到:我們畢竟不需要GC,因為我們有智能的指針。


一個再錯不過了。


智能指針確實有幫助:auto_ptr并且unique_ptr使用RAII概念,的確非常有用。它們是如此簡單,您可以很容易地自己編寫它們。


但是,當需要共享所有權時,這會變得更加困難:您可能會在多個線程之間共享,并且計數處理存在一些細微的問題。因此,自然會走向shared_ptr。


太好了,畢竟這就是Boost的目的,但這不是靈丹妙藥。實際上,主要的問題shared_ptr是它模擬了由GC實施的GC,Reference Counting但是您需要自己全部實施循環檢測... Urg


當然,這很weak_ptr麻煩,但是盡管如此,shared_ptr由于使用了這些周期,但不幸的是我已經看到內存泄漏了……而且當您處于多線程環境中時,這很難檢測!


4.解決方案是什么?


沒有靈丹妙藥,但是和往常一樣,這絕對是可行的。在沒有GC的情況下,需要明確所有權:


如果可能的話,寧愿在給定的時間只有一個所有者

如果沒有,請確保您的類圖沒有與所有權有關的任何周期,并通過巧妙地應用 weak_ptr

所以的確,擁有GC很棒。但是這不是小問題。同時,我們只需要卷起袖子。


查看完整回答
反對 回復 2019-12-07
  • 3 回答
  • 0 關注
  • 460 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號