Sun HotSpot 1.4.1 JVM学习总结

来源:互联网 发布:移动4g 网络 编辑:程序博客网 时间:2024/06/10 21:31
在Java 中gc是不被强制要求的,因此,各个厂商生产的 JVM 的性能如何,就极大的取决于gc的设计方案和实现原理。
在早期的 JVM 中,gc 在进行垃圾收集时,采用“引用计数法”,他的特点是通过记录对象被引用的次数来决定该对象是否应该标记为“垃圾收集状态”。如果某个对象,他的被引用数为“0”,则该对象会被标记为“垃圾收集状态”,在JVM 处于无操作状态时,由 gc 进行垃圾收集工作将其所占内存空间进行回收再利用。
现在的 JVM 大多采用“对象引用遍历法”,在遍历时,以某些对象为根构成一个有向图进行遍历。沿着有向图上的每条链路进行递归遍历,如果在遍历的过程中发现有这样一个对象,至少有一个根对象无法遍历到这个对象,那么不管其他根对象是否能够遍历到该对象,都将其标记为“垃圾回收状态”。
尽管各个厂商在具体实现的细节上有各种各样的差异,但是,就从大的思路上来说,基本上都是一致的,也就是说,先对要回收的对象进行标记,然后再进行回收。
说到垃圾回收,自然就少不了垃圾回收的相关技术。下面我就是一些基本的实现机制:
²         标记-清除收集器
²         标记-压缩收集器
²         复制收集器
²         增量收集器
²         分代收集器
²         并发收集器
²         并行收集器
在 Sun 的HotSpot 1.4.1中,它使用“分代收集器”把“堆”分为:新域、旧域以及永久域等三个主要的域。
对象在刚刚生成时会进入“新域”,在经过若干次的垃圾收集后,如果此对象仍然没有被标记为“垃圾回收状态”就会进入“旧域”,但这只是一个理论情况,实际情况是,有些“旧对象”仍然会留在新域中。而“永久域”作为一个独立的域通常不被认为是堆的一部分,他主要用来存放类和方法的框架结构。永久域默认大小为4m。运行程序时,JVM 会自动调整永久域的大小以满足需要。每次调整时,JVM 会对“堆”进行一次完全的垃圾收集。因此,虽然我们无法确切知道JVM在什么时候进行垃圾回收,但是有一点是确定的,那就是,如果用户在短时间内访问和调用大量的类及其方法时,JVM一定会进行垃圾收集工作。
默认状态下,HotSpot在新域中使用复制收集器。该域一般分为三个部分。第一部分为Eden,用于生成新的对象。另两部分称为救助空间,当Eden充满时,收集器停止应用程序,把所有可到达对象复制到当前的from救助空间,一旦当前的from救助空间充满,收集器则把可到达对象复制到当前的to救助空间。From和to救助空间互换角色。维持活动的对象将在救助空间不断复制,直到它们获得使用期并转入旧域。
因为应用程序生成的大部分对象是短寿命的。理想状态下,所有过渡对象在移出Eden空间时将被收集。如果能够这样的话,并且移出Eden空间的对象是长寿命的,那么理论上可以立即把它们移进旧域,避免在救助空间反复复制。但是,应用程序不能适合这种理想状态,因为它们有一小部分“中长寿命”的对象。最好是保持这些“中长寿命”的对象并放在新域中,因为复制小部分的对象总比压缩旧域廉价。这也就是我在前面为什么说“旧对象”不一定会进入旧域中。
 
 
>>未完待续...
0 0
原创粉丝点击