【Java】垃圾回收器

引用计数:一种简单但速度很慢的垃圾回收技术

每个对象都含有一个引用计数器,当有引用连接至对象时,计数器加1。但引用离开作用域或被置为 null 时,引用计数减1。

  • 管理引用计数的过程在整个程序生命周期中将持续发生。
  • 如果对象之间存在循环引用,可能会出现“对象应该被回收,但引用计数却不为零”的情况。

Java垃圾回收器的思想

对于任何“活”的对象,一定能最终追溯到其存活在堆栈或静态存储区之中的引用。由此,如果从堆栈和静态存储区开始,遍历所有的引用,就能找到所有“活”的对象。对于发现的每个引用,必须追踪它所引用的对象,然后是此对象包含的所有引用,如此反复进行,直到“根源于堆栈和静态存储区的引用”所形成的网络全部被访问为止。
基于这种思想,Java虚拟机将采用一种自适应的垃圾回收技术。有两种工作方式。
停止-复制:先暂停程序的运行(不属于后台回收模式),然后将所有存活的对象从当前堆复制到另一个堆,没有被复制的全部都是垃圾。对于这种方式,效率会降低,存在两个原因:

  • 首先,得有两个堆,然后得在这两个分离的堆之间来回倒腾,从而得维护比实际需要多一倍的空间。Java虚拟机对此问题的处理方式是,按需从堆中分配几块较大的内存,复制动作发生在这些大块内存之间。
  • 第二个问题在于复制。程序进入稳定状态之后,可能只会产生少量垃圾,甚至没有垃圾,尽管如此,复制式回收器仍然会将所有内存自一处复制到另一处,这很浪费。为了避免这种情形,Java虚拟机会进行检查:如果没有新垃圾产生,就会转换到另一种工作模式(即“自适应”);

标记-清扫:从堆栈和静态存储区出发,遍历所有的引用,进而找出所有存活的对象。每当它找到一个存活对象,就会给对象设一个标记,这个过程中不会回收任何对象。只有全部标记工作完成的时候,清理动作才会开始。在清理过程中,没有标记的对象将被释放,不会发生任何复制动作。所以剩下的堆空间是不连续的,垃圾回收器要是希望得到连续空间的话,就得重新整理剩下的对象。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容