來源:互聯網
上載者:User
關鍵字
JAVA
Reference
Counting
Python
Perl
在學習JAVA GC的時候,看到PHP Perl Python 記憶體回收的時候使用了引用計數法(Reference Counting),這是為什麼了?有什麼原因嗎?JAVA卻不是。
回複內容:
看到PHP Perl Python 記憶體回收的時候都是引用計數法,
我記得Python不是純粹的引用計數。
這是為什麼了?有什麼原因嗎?
很可能是因為實現簡單。
JAVA卻不是。
人家也不是指令碼語言啊。知乎現在已經沒什麼人噴那句“問為什麼之前,請先問是不是”了吧……至少 V8 就不是…… PyPy 好像也不是……Java的GC是generational gc,V8的也是。總體來說,gc如何implement應該需要綜合efficiency,complexity,fragmentation等考慮,同意上面的說法大多數情況下指令碼語言考慮的就是簡單啊!re ference counting最簡單了指令碼語言的記憶體回收方式通常有兩種
1 引用計數,比如cpython
優點: 可以即時釋放對象,不依賴gc
缺點: 無法處理循環參考,需要gc去檢測循環參考;
虛擬機器實現複雜,引用計數的加減處理要很小心。
2 標記刪除法,如lua
優點: 虛擬機器實現簡單,也不用擔心循環參考
缺點: 不能即時刪除對象,必須依賴gc來回收記憶體。引用計數器無法解決循環參考的問題引用計數 實現簡單效能高,但是有循環參考的問題
根集掃描,沒有這個問題但是效能慢。
所以用計數來釋放一部分然後gc用根集掃描現在一般gc都會使用多種機制,很少單單一個引用計數的。
順便吐槽一下完全沒有引用計數的語言,比如java, 開啟一個檔案都要自己在finalize裡關是什麼意思,還是不是全自動垃圾收集啦。。。
要是自己不關就只能聽gc的天由命,連什麼時候關的都不知道。。。指令碼語言不清楚,說說java吧,應該都差別不大
上古時期就不是了吧,引用計數法有致命的缺陷,無法解決循環參考的問題,
後來用的演算法都是最佳化後的演算法,
比如複製收集,多適用年輕代,(臨時對象多永久對象少)
比如標記清除和標記整理,多用於年老代(永久對象多,臨時對象少)
用詞不太專業,見笑