您的位置:首页 > 其它

4种GC方法+分代回收+触发GC情况+内存申请过程

2017-04-24 16:06 288 查看

①引用计数

对象增加一个引用时,引用数+1。减少一个时,引用数-1。当进行垃圾回收时,只回收引用数为0的对象。面对互相引用无解,方法比较老,基本弃用

②标记+清除

从根节点遍历标记对象,然后遍历整个堆,清除没有标记的对象。

缺点:运行效率不高,产生了内存碎片,运行时需要暂停应用

③复制

将内存分为2个区域(区域a和区域b),一个区域空着(区域a),另一个区域(区域b)放对象。垃圾回收时,将区域b还在引用的对象复制到空着的区域(区域a)中去,并且当前区域(区域b)清空。如此反复

缺点:复制到a区域的时候,同时进行了内存整理,没有内存碎片。但是需要2倍的内存

④标记+整理

从根节点遍历标记对象,然后遍历整个堆,清除没有标记的对象,并且将有标记的对象压缩到一块的区域内

特点:没有内存碎片,也不需要2倍内存

分代回收中将内存分成了3代

①年轻代。

年轻代内分为eden区和两个survivor区。eden区存储刚刚建立的新对象。eden区满后,将还存活的对象复制到一个survivor区中,然后这个survivor区满了以后,将还存活的对象复制到第二个survivor区中去,同时清空第一个survivor区。第二个区满了以后,将第一个survivor区中的存活的对象复制到年老代(可能要多次GC以后还存活的对象才能复制到年老代),剩下的活的引用 对象复制到第一个survivor区,清空第二个survivor区。

没错,两个survivor区用的就是GC中的复制方法,oh yeah。

年轻代区域一般比较小。可以有多个survivor区,不一定非要2个。

②年老代。

年老代存储的是生命周期比较长的对象,年老代用标记+清理的方法进行GC

③持久代。

持久代一般存放静态对象,class,方法等。持久代对垃圾回收没有影响,但是有些应用可能动态生成火这调用一些class,例如hibernate等,这时需要设置一个比较大的持久代来存放这些运行中新增的类。通过-XX:MaxPermSize=<N>设置

摘抄:

什么情况下触发垃圾回收

由于对象进行了分代处理,因此垃圾回收区域、时间也不一样。GC有两种类型:Scavenge GCFull GC

Scavenge GC

一般情况下,当新对象生成,并且在Eden申请空间失败时,就会触发Scavenge GC,对Eden区域进行GC,清除非存活对象,并且把尚且存活的对象移动到Survivor区。然后整理Survivor的两个区。这种方式的GC是对年轻代的Eden区进行,不会影响到年老代。因为大部分对象都是从Eden区开始的,同时Eden区不会分配的很大,所以Eden区的GC会频繁进行。因而,一般在这里需要使用速度快、效率高的算法,使Eden去能尽快空闲出来。

Full GC

对整个堆进行整理,包括Young、Tenured和Perm。Full
GC因为需要对整个对进行回收,所以比Scavenge GC要慢,因此应该尽可能减少Full GC的次数。在对JVM调优的过程中,很大一部分工作就是对于FullGC的调节。有如下原因可能导致Full GC:

· 年老代(Tenured)被写满

· 持久代(Perm)被写满

· System.gc()被显示调用

·上一次GC之后Heap的各域分配策略动态变化

当一个URL被访问时,内存申请过程如下:

A. JVM会试图为相关Java对象在Eden中初始化一块内存区域

B. 当Eden空间足够时,内存申请结束。否则到下一步

C. JVM试图释放在Eden中所有不活跃的对象(这属于1或更高级的垃圾回收), 释放后若Eden空间仍然不足以放入新对象,则试图将部分Eden中活跃对象放入Survivor区

D. Survivor区被用来作为Eden及OLD的中间交换区域,当OLD区空间足够时,Survivor区的对象会被移到Old区,否则会被保留在Survivor区

E. 当OLD区空间不够时,JVM会在OLD区进行完全的垃圾收集(0级)

F. 完全垃圾收集后,若Survivor及OLD区仍然无法存放从Eden复制过来的部分对象,导致JVM无法在Eden区为新对象创建内存区域,则出现”out of memory错误”

JVM调优建议:

ms/mx:定义YOUNG+OLD段的总尺寸,ms为JVM启动时YOUNG+OLD的内存大小;mx为最大可占用的YOUNG+OLD内存大小。在用户生产环境上一般将这两个值设为相同,以减少运行期间系统在内存申请上所花的开销。

NewSize/MaxNewSize:定义YOUNG段的尺寸,NewSize为JVM启动时YOUNG的内存大小;MaxNewSize为最大可占用的YOUNG内存大小。在用户生产环境上一般将这两个值设为相同,以减少运行期间系统在内存申请上所花的开销。

PermSize/MaxPermSize:定义Perm段的尺寸,PermSize为JVM启动时Perm的内存大小;MaxPermSize为最大可占用的Perm内存大小。在用户生产环境上一般将这两个值设为相同,以减少运行期间系统在内存申请上所花的开销。

SurvivorRatio:设置Survivor空间和Eden空间的比例


                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  gc