垃圾回收器如何工作
- 引用计数
引用计数是一种简单但速度很慢的垃圾回收计数。每个对象都含有一个引用计数器,当有一个引用连接至对象时,引用加1,当 引用离开作用域或被置为null时,引用减1。当对象的引用变成0的时候,这个对象会被回收。但是这种方法有个缺陷,就是当两个对象互相引用,而且这个对象都不再需要的时候,两个对象都应该被回收,但是因为互相持有引用,所以引用计数不为0,导致它们都不能被回收 - 停止-复制
从堆栈和静态存储区开始,遍历所有的引用,就能找到所有活的引用。对于找到的引用,继续追踪它所引用的对象,如此反复进行。先暂停程序的运行,把“活”的对象复制到一个新堆,复制之后,它们是一个紧挨着一个的。对于这种“复制式回收器“,效率会降低,一是维护需要多一倍的空间用来来回复制,二是程序稳定之后,产生的少量的垃圾,来回复制反而是作了很多无用功。 - 标记-清扫
跟停止-复制法同样的思路,从堆栈和静态存储区出发,遍历所用的对象,给找到的对象一个标记,最后把没有标记的对象释放。
自适应
在Java虚拟机中,内存分配以较大的块为单位,如果对象较大,它会占用单独的块。对于“停止-复制”,有了块之后,垃圾回收器可以往废弃的块里拷贝对象。每个块都用相应的代数来记录它是否存活。垃圾回收器会进行定期的清理工作,大型对象往往不会被复制,内含的小型对象则被复制并整理。Java虚拟机会进行监视,如何所有对象都很稳定,垃圾回收器的效率变慢时,就切换到“标记-清扫”方式。而当内存中碎片较多时,就切换到“停止-复制”方式。这就是“自适应”技术。
以上皆个人学习的总结,如有不对之处,欢迎指出。邮箱:527219336@qq.com