為什麼沒有編程語言的內存管理是手動管理與自動垃圾回收相結合的?

要麼是c,c++這種完全靠自己free的,一不小心就內存泄露的

要麼是java,python這種完全依賴gc的,然後gc的時機完全沒法掌控,一次大規模full gc就可能帶來大的latency。

為啥不能兩者相結合呢?如果想自己free就自己free,自己忘了free也有gc幫忙free。

還是我孤陋寡聞,其實有這樣的語言?


C#你可以手動管理啊,pin下來就是不給gc,WeakReference就是對象測試,調用Dispose()就是強制釋放。不過因為gc有內存池,所以嚴格的來講這不一定會調用操作系統的釋放函數。在幾乎所有場合下都夠用。

而且C++並不能100%算成完全靠自己free。當你大量使用weak_ptr/shared_ptr/unique_ptr並發現它實際上不會成為瓶頸的時候,你就從內存的泥潭裡解放出來了,雖然沒有C#那麼徹底。


C/C++ 完全靠手動這個容易解釋 —— 總有對性能和 predictability 需求極高的場合。

至於其它語言,我並不認為有完美的解決方案。主要的考慮是 latency 和 overhead。一次回收大量垃圾,自然總 overhead 最小,但是 latency 就高了。一次回收一小部分,latency 比較低,但是總的 overhead 比較大。這中間的權衡需要在 runtime 收集信息來總體裁斷,編寫代碼的時候靜態考慮的效果並不好。所以現代 GC 的原則就是說:我知道所有信息,我有啟發式的演算法,可以保證總體效率。不希望讓程序員干涉。

而且,有 GC 的語言,數據的生命周期並不好判斷:一是語言會避免像 C/C++ 那樣做 value copy,二是經常用在 undeterministic 的場合(UI、event-driven)。這種時候,讓 GC 本身根據 global knowledge 來做分代,可能比程序員自己分析要好。

Java 規範里規定 System.gc( ) 只是一個 hint,這個我覺得多少有些太自負了。Lua 的 collectgarbage 是可以確定的調用 GC 的。但是也只是選擇 GC 調用的時機,因為 GC 擁有整體內存的 knowledge,這個 global knowledge 還真的很難用一個清晰的介面呈現給程序員,所以還是作為一個黑箱好了。


rust, optional gc.


Objective-C目前也可以是說手動與自動都可以的啊。

雖然Objective-C自動管理並不是真正意義上的自動垃圾回收,但是對於使用者來說不用自己管理內存了,實際效果差不多啊。

當然一個源文件中只能存在一種模式(ARC或者MRC),但是文件之間可以使用不同內存管理模式的


Bohem GC for C/C++

Boehm garbage collector

不用謝。


題主用過 std::shared_ptr 么喵…

寫過 Luac 或者 node_gyp 么喵…


單純覺得可能沒啥必要。對於有的帶有垃圾回收的語言來說手動管理問題反而會帶來一些沒有比較的麻煩。


智能指針唄 以objective c為代表的ARC


OC

ARC + @autoreleasepoll


推薦閱讀:

linux怎麼管理空閑內存?
如何釋放Python佔用的內存?
看遊戲引擎架構內存管理有個地方不太清楚?
C語言和內存管理有什麼關係?為什麼說學習C語言的關鍵在內存管理?
講C語言內存管理的書籍或者博客?

TAG:編程語言 | 內存管理 |