Java背后的秘密之Java的垃圾收集器04

JVM垃圾收集机制:
Java语言在推出时或者说直到现在,有两个最为引人注目的特性,即跨平台特性和自动垃圾回收。所谓自动垃圾回收,JVM能够自动识别Java堆中无用的对象(垃圾),并且释放它们所占的空间,以便其他对象使用。垃圾收集机制把程序员从恼人的内存管理中解救了出来,使之腾出更多的精力去考虑其他程序的问题。这无疑相比在此之前的一些语言(如:C++),减轻了开发人员的工作负担。JVM的垃圾回收由JVM的垃圾回收器来实现,不同的JVM在这些方面会有些许的不同。另外垃圾回收器除了进行垃圾回收外,还会对Java的堆空间碎片进行压缩,以便能够更有效的利用内存空间。
疑问:
1.垃圾收集机制真的解放了开发人员吗?
回答:不一定,从某种程度来看,若想真的避免内存泄漏,还要看开发人员或设计人员的经验与水平。

2.垃圾收集机制真的就是一劳永逸的解决问题的“银弹”吗?
回答:当然不是,如果使用不当反会被其所伤,对程序性能造成重大伤害。

3.怎么办呢?
回答:1.水平经验的积累;2.折中思想的运用。


垃圾收集的实现:
(1)、引用计数:早期JDK版本采用;
优点:交织在程序运行之中运行较快;
缺点:由于计数从而带来了额外开销;不能识别循环引用;

(2)、跟踪收集:
优点:可以识别循环引用,不会交织在程序运行过程中;
缺点:需要维护一张对象引用全景图,增加了内存开销,如果是一个复杂的引用,那么遍历这张全景图的时候,性能开销也会很大。

(3)、基于对象跟踪的分代增量收集:当今大部分的虚拟机产品,都使用这种收集技术。如:SUN的HotSpot(我们常用的),IBM的JVM产品,BEA的weblogic等。
优点:不同时期收集所有代,因此可以使垃圾收集时间更短;可以针对不同对象采用不同的收集算法,从而充分利用系统资源。
缺点:收集算法复杂,开销巨大,这也是Java性能与内存使用问题的主要来源之一。

具体实现,以SUN的HotSpot为例说明:
SUN的JVM将整个堆分为三代,即三个区域,如下图所见:



这个三代分别为Young(年轻代)、Tenured(年老代)、Perm(持久代)。
年轻代:对这个区域的GC是相对高效和快速的,这个区域中经历了若干次GC仍然存活的对象,“晋升”到年老代。

年老代:内存占用较大的对象,即重量级对象,则一开始直接被分配到年老代。

持久代:这一代中存放长时间存活的对象,如Class对象基础数据信息、全局应用配置信息等。

何时进行GC呢?
很简单当然是在Heap不够时,年轻代不够就对年轻代做GC,年老代不够就对年老代做GC,但是收集算法都是不同的。注意年老代对象的回收(全收集)远比年轻代对象的回收(会触发一个小收集)耗时耗力,所以全收集对应用系统性能会造成极大伤害,因此要尽力避免。



转载来源www.boobooke.com/bbs->J2EE专区->蓝山作品—Java背后的秘密(汇总) 



猜你喜欢

转载自blog.csdn.net/sunchaoenter/article/details/7946704