【叶凡网络】浅谈JVM调优的分代垃圾回收详述
- 2014-02-16 10:31:37 | 新闻来源:叶凡网络 | 点击量:812
适用情况:对响应时间有高要求”多CPU对应用响应时间有较高要求的中、大型应用。举例:Web服务器/应用服务器、电信交换、集成开发环境。基于这样一个事实:不同的对象的生命周期是不一样的因此,分代的垃圾回收战略。不同生命周期的对象可以采取不同的收集方式,以便提高回收效率。会产生大量的对象,Java顺序运行的过程中。其中有些对象是与业务信息相关,比方Http请求中的Session对象、线程、Socket连接,这类对象跟业务直接挂钩,因此生命周期比较长。但是还有一些对象,主要是顺序运行过程中生成的临时变量,这些对象生命周期会比较短,比方:String对象,由于其不变类的特性,系统会产生大量的这些对象,有些对象甚至只用一次即可回收。
不进行对象存活时间区分的情况下,试想每次垃圾回收都是对整个堆空间进行回收,花费时间相对会长,同时,因为每次回收都需要遍历所有存活对象,但实际上,对于生命周期长的对象而言,这种遍历是没有效果的因为可能进行了很多次遍历,但是依旧存在因此,分代垃圾回收采用分治的思想,进行代的划分,把不同生命周期的对象放在不同代上,不同代上采用最适合它垃圾回收方式进行回收。
与垃圾收集要收集的Java对象关系不大。年轻代和年老代的划分是对垃圾收集影响比较大的虚拟机中的共划分为三个代:年轻代(YoungGener年老点(OldGener和持久代(PermanGener其中耐久代主要存放的Java类的类信息。两个Survivor区(一般而言)大部分对象在Eden区中生成。当Eden区满时,所有新生成的对象首先都是放在年轻代的年轻代的目标就是尽可能快速的收集掉那些生命周期短的对象。年轻代分三个区。一个Eden区。还存活的对象将被复制到Survivor区(两个中的一个)当这个Survivor区满时,此区的存活对象将被复制到另外一个Survivor区,当这个Survivor去也满了时候,从第一个Survivor区复制过来的并且此时还存活的对象,将被复制“年老区(Tenur需要注意,Survivor两个区是对称的没先后关系,所以同一个区中可能同时存在从Eden复制过来 对象,和从前一个Survivor复制过来的对象,而复制到年老区的只有从第一个Survivor去过来的对象。而且,Survivor区总有一个是空的同时,根据顺序需要,Survivor区是可以配置为多个的多于两个)这样可以增加对象在年轻代中的存在时间,减少被放到年老代的可能。
就会被放到年老代中。因此,年轻代中经历了N次垃圾回收后仍然存活的对象。可以认为年老代中存放的都是一些生命周期较长的对象。如今Java类、方法等。耐久代对垃圾回收没有显著影响,用于存放静态文件。但是有些应用可能动态生成或者调用一些class例如Hibern等,这种时候需要设置一个比较大的耐久代空间来存放这些运行过程中新增的类。耐久代大小通过-XX:MaxPermSize=<N>进行设置。
什么情况下触发垃圾回收,因此垃圾回收区域、时间也不一样。GC有两种类型:ScavengGC和FullGC由于对象进行了分代处理。当新对象生成,一般情况下。并且在Eden申请空间失败时,就会触发ScavengGC对Eden区域进行GC清除非存活对象,并且把尚且存活的对象移动到Survivor区。然后整理Survivor两个区。这种方式的GC对年轻代的Eden区进行,不会影响到年老代。因为大部分对象都是从Eden区开始的同时Eden区不会分配的很大,所以Eden区的GC会频繁进行。因而,一般在这里需要使用速度快、效率高的算法,使Eden去能尽快空闲进去。
包括YoungTenur和PermFullGC因为需要对整个对进行回收,对整个堆进行整理。所以比ScavengGC要慢,因此应该尽可能减少FullGC次数。对JVM调优的过程中,很大一局部工作就是对于FullGC调节。有如下原因可能导致FullGC,因为无需多线程交互,用单线程处置所有垃圾回收工作。所以效率比较高。但是也无法使用多处理器的优势,所以此收集器适合单处置器机器。当然,此收集器也可以用在小数据量(100M左右)情况下的多处置器机器上。可以使用-XX:+UseSerialGC打开。
因此可以减少垃圾回收时间。一般在多线程多处置器机器上使用。使用-XX:+UseParallelGC.打开。并行收集器在J2SE5.0第六6更新上引入,对年轻代进行并行垃圾回收。JavaSE6.0中进行了增强--可以对年老代进行并行收集。如果年老代不使用并发收集的话,默认是使用单线程进行垃圾回收,因此会制约扩展能力。使用-XX:+UseParallelOldGC打开。
通过-XX:MaxGCPauseMillis=<N>指定。<N>为毫秒.如果指定了此值的话,最大垃圾回收暂停:指定垃圾回收时的最长暂停时间。堆大小和垃圾回收相关参数会进行调整以达到指定值。设定此值可能会减少应用的吞吐量;通过-XX:GCTimeRatio=<N>来设定,吞吐量:吞吐量为垃圾回收时间与非垃圾回收时间的比值。公式为1/1+N例如,-XX:GCTimeRatio=19时,表示5%时间用于垃圾回收。默认情况为99即1%时间用于垃圾回收。
此收集器适合对响应时间要求比较高的中、大规模应用。使用-XX:+UseConcMarkSweepGC打开。可以保证大部分工作都并发进行(应用不停止)垃圾回收只暂停很少的时间。应用不停止的情况下使用独立的垃圾回收线程,并发收集器主要减少年老代的暂停时间。跟踪可达对象。每个年老代垃圾回收周期中,收集初期并发收集器 会对整个应用进行简短的暂停,收集中还会再暂停一次。第二次暂停会比第一次稍长,此过程中多个线程同时进行垃圾回收工作。并发收集局部使用K/N个可用处置器进行回收,并发收集器使用处置器换来短暂的停顿时间。一个N个处理器的系统上。一般情况下1<=K<=N/4,设置为incrementmode模式也可获得较短的停顿时间。只有一个处理器的主机上使用并发收集器。
所以有些垃圾可能在垃圾回收进行完成时产生,浮动垃圾:由于在应用运行的同时进行垃圾回收。这样就造成了FloatGarbag这些垃圾需要在下次垃圾回收周期时才干回收掉。所以,并发收集器一般需要20%预留空间用于这些浮动垃圾。所以需要保证堆在垃圾回收的这段时间有足够的空间供程序使用,ConcurrModeFailur并发收集器在应用运行时进行收集。否则垃圾回收还未完成,堆空间先满了这种情况下将会发生“并发模式失败”此时整个应用将会暂停,进行垃圾回收。所以必需保证收集完成之前有足够的内存空间供程序使用,启动并发收集器:因为并发收集在应用运行时进行收集。否则会出现“ConcurrModeFailur通过设置-XX:CMSInitiatingOccupancyFraction=<N>指定还有多少剩余堆时开始执行并发收集。
上一篇:【叶凡网络】马其顿致数十人中毒一所中学遭毒气袭击
下一篇:【叶凡网络】贵阳通报10起典型案例集中开展“打苍蝇”工作