JAVA中 的垃圾回收机制总体来说分为以下几种
1、引用计数器方法:
每个对象都有一个引用计数器,当引用连接至对象时,引用计数器加一,当引用离开对象或者被置为null时,引用计数器减一。这个过程会在整个程序生命周期中运行,垃圾回收器会在含有全部对象的列表上遍历,如果引用计数器为0,那么将其释放掉,如果不为0,则不释放。这种方法有个缺陷,就是当对象循环应用时,定位这个循环引用的对象工作量极大。所以这种垃圾回收机制几乎从来没有被实现过。
2、自适应的垃圾回收机制
A、停止-复制机制:垃圾回收器会从堆栈或者静态区域开始扫描,如果被引用的对象就是存活的。这种实现方式会先暂停程序的运行,然后把存活的对象从当前堆复制到新的堆并且紧凑排列,同时修改这些对象的引用。这种实现方式效率比较低,主要有以下几个原因:1、需要两个堆,一个是旧堆一个是新堆,并且将旧堆的对象复制到新堆中,这个需要两倍的存储空间。2、当程序进入稳定期之后一般很少产生垃圾,所以还一味的复制回收就显得浪费资源了。
B、标记-清扫机制:垃圾回收器会从堆栈或者静态区域开始扫描,如果被引用的对象就是存活的。每当找到一个存活的对象时,就将其标记起来,标记的这个过程不会回收任何对象。当标记工作完成之后,清理工作才开始,清理过程中,没有被标记的区域会被回收,但是标记的区域不会有任何动作产生。当清理工作完成之后,所使用的内存区域并不连续,如果需要的话,还有一个整理当前使用区域的工作。一般用途而言,这种方法相当慢,但是当知道产生少量垃圾或者不产生垃圾的时候,这种方法就很快了。
C、代数回收法:以上的两种方法内存都是以块为单位进行操作的,如果对象较大的话,会占用单独的块,如果是这样的话,垃圾回收器就可以往废弃的块中拷贝对象了,每个块都有相应的代数来记录其是否存活。一般块被引用的话,其代数就会增加。这样的话大型对象就不会被复制,而小型的特别是一些生命周期短的临时对象就会被整理并回收。
总结:自适应垃圾回收机制的精华在于其可以在以上三种机制下动态转换。JVM会进行监视,如果所有对象都想对稳定的话,垃圾回收率降低的话,会使用“标记-清理”机制进行垃圾回收,同时,JVM会监视产生的碎片情况,如果产生大量碎片的话,就会切换到"停止-复制"机制进行操作。