为什么脚本语言GC使用了引用计数法?
时间:2021-07-01 10:21:17
帮助过:4人阅读
在学习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吧,应该都差别不大
上古时期就不是了吧,引用计数法有致命的缺陷,无法解决循环引用的问题,
后来用的算法都是优化后的算法,
比如复制收集,多适用年轻代,(临时对象多永久对象少)
比如标记清除和标记整理,多用于年老代(永久对象多,临时对象少)
用词不太专业,见笑