Java虚拟机中堆的实现有点像一个传送带,每分配一个对象,它就往前移动一格。这就意味着
对象存储空间的分配速度非常快。
1、垃圾回收技术
一、
找到所有存活的对象
(1)
引用计数,是一种简单但速度很慢的垃圾回收技术。每个对象都含有一个引用计数器,当有引用连接到对象时,引用计数加1.当引用离开作用域或被置为NULL时,引用计数减1.虽然管理引用记数的开销不大,但这项开销在整个程序生命周期中将持续发生。垃圾回收器会在含有全部对象的列表上遍历,当发现某个对象的引用计数为0时,就释放其占用的空间。这种方法有个缺陷,如果对象之间存在循环引用,可能会出现“对象应该被回收,但引用计数不为零”的情况。对垃圾回收器而言,定位这样的交互自引用的对象组所需的工作量极大。 引用计数
常用来说明垃圾收集的工作方式,但似乎从未被应用到任何一种java虚拟机中。
(2)
自适应的垃圾回收技术,它依据的思想是:对任何“活”的对象,一定能最终追溯到其存活在堆栈或静态存储区之中的引用。这个引用链条可能会穿过数个对象层次。由此,如果
从堆栈和静态存储区开始,遍历所有的引用,就能找到所有“活”的对象。对于发现的每个引用,必须追踪它所引用的对象,然后是此对象对象包含的所有引用,如此反复进行,直到“根源于堆栈和静态存储区的引用”所形成的网络全部被访问为止。
二、
处理所有存活的对象
(1)
停止--复制。这意味着先暂停程序的运行(所以它不属于后台回收模式),然后将所有存活的对象从当前堆栈复制到另一个堆,没有被复制的全部是垃圾。当对象被复制到新堆时,它们是一个挨着一个的,所以新堆保持紧凑排列,。
当把对象从一处搬到另一处时,所有指向它的那些引用都必须修正。位于堆栈或静态存储区的引用可以直接修正,但可能还有其他指向这些对象的引用,它们在遍历的过程中才能被找到。
对于这种复制式回收器,效率为降低。原因在于1、维护比实际需要多一倍的空间。
某些Java虚拟机处理方法是:按需从堆中分配几块较大的内存,复制动作发生在这些大块内存之间。2、在于复制。程序进入稳定状态之后,可能只会产生少量垃圾,甚至没有垃圾。复制式回收器仍然会将所有内存自一处复制到另一处,这很浪费。
为了解决问题,一些Java虚拟机会进行检查:要是没有新垃圾产生,就会转换到另一种工作模式标记--清扫。
(2)
标记--清扫。其所依据的同样是从堆栈和静态存储发,遍历所有的引用,进而找出所有存活的对象。每当它找到一个存活对象,就会给对象设一个标记,这个过程不会回收任何对象。只有全部标记工作完成的时候,清理动作才会开始。在清理过程中,没有标记的对象将被释放,不会发生任何复制动作。(标记--清扫工作也必须在程序暂停情况下才能进行)
三、实际垃圾回收机制设计
现行的垃圾回收器用分代的方式来采用不同的回收设计。分代的基本思路是根据对象生存时间的长短,把堆内存分成3个代:
Young(年轻代)
Old(老年代)
Permanent(永久代)
垃圾回收器会根据不同代的特点采用不同的回收算法,从而充分利用各种回收算法的优点。
采用“分代回收”的策略基于如下两点事实:
(1)、绝大对数的对象不会被长时间引用,这些对象在其Young期间就会被回收。
(2)、很老的对象(生存时间很长)和很新的对象(生存时间很短)之间很少存在相互引用的情况。
根据上面两点事实,对于Young代的对象而言,大部分对象都会很快就进入不可达状态,只有少量的对象能熬到垃圾回收执行时,而垃圾回收器只需要保留Young代中处于可达状态的对象,如果采用复制算法只需要少量的复制成本,因此大部分垃圾回收器对Young代都采用复制法。
Young代由1个Eden区和2个Survivor区构成。绝大多数对象先分配到Eden区中,Survivor区中的对象都至少在Young代中经历过一次垃圾回收,所以这些对象在被转移到Old代之前会先保留在Survivor空间中。同一时间2个Surivivor空间有一个用来保存对象,而另一个是空的,用来在下次垃圾回收时保存Young代中的对象。每次复制就是将Eden和第1个Survivor的可达对象复制到第2个Survivor区,然后清空Eden与第1个Survivor区。
Old代
Old代的大部分对象都是经过多次垃圾回收存活的对象,随着时间越久,Old代对象就会越多,因此Old代的空间要比Young代空间更大。出于这两点考虑,Old代的垃圾回收具有如下两个特征:
(1)、Old代垃圾回收的执行频率无需太高,因为很少有对象会死掉。
(2)、每次对Old代执行垃圾回收需要更长时间来完成。
基于以上考虑,垃圾回收器通常会使用标记压缩算法。这种算法可以避免复制Old代的大量对象。
Permanent代
Permanent代主要装载Class、方法等信息,默认为64M,垃圾回收机制通常不会回收Permanent代中的对象。对于那些需要加载很多类的服务器程序,往往需要加大Permanent代内存,否则可能因为内存不足而导致程序终止。
当Young代的内存将要用完的时候,垃圾回收机制会对Young代进行垃圾回收,垃圾回收机制会采用较高的频率对Young代进行扫描和回收。因为这种回收的系统开销比较小,因此也被称为次要回收。当然Old代的内存将要用完时,垃圾回机制会进行完全回收,也就是对Young代和Old代都要进行回收,此时回收成本就大得多了,因此也称为主要回收。
这种自适应技术可称为----
自适应的、分代的、停止--复制、标记--清扫式垃圾回收器。
分享到:
相关推荐
Java垃圾回收机制(GC)是Java编程语言的关键特性,它自动管理内存,释放不再使用的对象,以防止内存泄漏。GC的运作方式主要有两种策略:引用计数和对象引用遍历。 引用计数是一种简单但不完美的方法。每个对象都有...
### Java垃圾回收机制详解 #### 一、引言 Java作为一种高级编程语言,自问世以来便因其自动内存管理和垃圾回收机制而备受青睐。本篇文章旨在深入探讨Java垃圾回收(Garbage Collection, GC)机制的工作原理及其...
Java垃圾回收机制详解和调优.doc Java垃圾回收机制详解和调优.doc Java垃圾回收机制详解和调优.doc Java垃圾回收机制详解和调优.doc Java垃圾回收机制详解和调优.doc Java垃圾回收机制详解和调优.doc Java垃圾回收...
Java垃圾回收机制总结 Java垃圾回收机制是Java虚拟机(JVM)中的一种机制,用于防止内存泄露和有效地使用空闲的内存。垃圾回收机制的主要目的是为了回收无用的对象占用的内存空间,使该空间可被程序再次使用。 ...
Java中类的生命周期与java垃圾回收机制
【Java面试题】Java垃圾回收机制
Java垃圾回收机制简介 Java垃圾回收机制是Java语言中的一种自动内存管理机制,它可以帮助程序员更好地编写Java应用程序,而不需要手动编写垃圾回收相关的代码。这篇文章将会介绍Java垃圾回收机制的基本概念和原理,...
Java垃圾回收机制是Java编程中至关重要的一部分,它自动管理内存,释放不再使用的对象,避免内存泄漏,并优化内存使用。Java虚拟机(JVM)的堆内存是存放对象的主要区域,当对象通过new等指令创建后,垃圾回收机制...
浅谈 JAVA 垃圾回收机制 Java 垃圾回收机制是 Java 语言中的一种自动内存管理机制,它可以自动回收内存中的垃圾,避免代码运行时由于忘记释放对象而带来的内存泄漏问题。 Java 中的垃圾回收机制主要通过两种算法来...
Java垃圾回收机制详解 Java垃圾回收机制是Java虚拟机(JVM)中的一种自动管理内存的机制,它可以自动地将不再使用的对象从内存中回收,以释放更多的内存空间供其他对象使用。本文将详细介绍Java垃圾回收机制的工作...
Java垃圾回收机制是Java编程语言的关键特性,负责自动管理程序中的内存,确保程序高效、稳定地运行。在Java虚拟机(JVM)中,垃圾回收的主要任务是识别并清理不再被程序使用的对象,以避免内存泄漏。以下是关于Java...