JDK5.0垃圾收集优化之–Don’t Pause
作者:江南白衣,最新版链接:http://blog.csdn.net/calvinxiu/archive/2007/05/18/1614473.aspx,版权所有,转载请保留原文链接。 原本想把题目更简单的定为–《不要停》的,但还是自己YY一下就算了。 Java开发Server最大的障碍,就是JDK1.4版之前的的串行垃圾收集机制会引起长时间的服务暂停,明白原理后,想想那些用JDK1.3写Server的先辈,不得不后怕。 好在JDK1.4已开始支持多线程并行的后台垃圾收集算法,JDK5.0则优化了默认值的设置。 一、参考资料: Tuning Garbage Collection with the 5.0 Java Virtual Machine 官方指南。 Hotspot memory management whitepaper 官方白皮书。 Java Tuning White Paper 官方文档。 FAQ about Garbage Collection in the Hotspot 官方FAQ,JVM1.4.2。 Java HotSpot 虚拟机中的垃圾收集 JavaOne2004上的中文ppt A Collection of JVM Options JVM选项的超完整收集。 二、基本概念 1、堆(Heap) JVM管理的内存叫堆。在32Bit操作系统上有1.5G-2G的限制,而64Bit的就没有。 JVM初始分配的内存由-Xms指定,默认是物理内存的1/64但小于1G。 JVM最大分配的内存由-Xmx指定,默认是物理内存的1/4但小于1G。 默认空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制,可以由-XX:MinHeapFreeRatio=指定。 默认空余堆内存大于70%时,JVM会减少堆直到-Xms的最小限制,可以由-XX:MaxHeapFreeRatio=指定。 服务器一般设置-Xms、-Xmx相等以避免在每次GC 后调整堆的大小,所以上面的两个参数没啥用。 2.基本收集算法 复制:将堆内分成两个相同空间,从根(ThreadLocal的对象,静态对象)开始访问每一个关联的活跃对象,将空间A的活跃对象全部复制到空间B,然后一次性回收整个空间A。因为只访问活跃对象,将所有活动对象复制走之后就清空整个空间,不用去访问死对象,所以遍历空间的成本较小,但需要巨大的复制成本和较多的内存。 标记清除(mark-sweep):收集器先从根开始访问所有活跃对象,标记为活跃对象。然后再遍历一次整个内存区域,把所有没有标记活跃的对象进行回收处理。该算法遍历整个空间的成本较大暂停时间随空间大小线性增大,而且整理后堆里的碎片很多。 标记整理(mark-sweep-compact):综合了上述两者的做法和优点,先标记活跃对象,然后将其合并成较大的内存块。 可见,没有免费的午餐,无论采用复制还是标记清除算法,自动的东西都要付出很大的性能代价。 […]