jvm中分代垃圾回收和触发垃圾回收
来源:互联网 发布:linux查看文件多大命令 编辑:程序博客网 时间:2024/05/14 08:32
如图所示,在HotSpot虚拟机中共划分有三个代:年轻代(young generation),年老代(old generation)和持久代(permanent generation)。实际上真正有意义的是年轻代和年老代,对象的生成与消亡都发生在这两个区域。
持久代(permanent generation)
在开始介绍年轻代和年老代之前,先来说一说持久代吧。
持久代的主要作用是存放java类等静态化的信息,可以看作是方法区的一部分。垃圾回收对持久代的影响并不大,只有某些需要动态生成类的应用才需要去关注这个区域的大小,可以通过-XX:MaxPermSize=<N>进行设置。
持久代是个比较神奇的概念,应该是Hotspot虚拟机里所特有的一个代。它是方法区的一部分,按常理不应该属于堆。并且在通过jvm参数设定各个区域大小的时候,可以很明显的发现持久代和堆的大小是需要分别指定的,两者不是一个整体。但是网络上铺天盖地的资料里都把它归属于堆,对此我一直感到无法理解,一种可能的解释是在早期的Hotspot虚拟机中,持久代就是堆的一部分。如果有高人清楚这么归类的原因,还望解惑。
年轻代(young generation)
年轻代是JVM堆中最常发生垃圾回收的区域,所有对象都生成于此。
如上图所示,年轻代一般可以分成三个区域,其中一个是Eden区,另外的两个From和To都是Survivor区。一般新生成的对象都出现在Eden区,当Eden区被填满时,所有经过垃圾回收还存活的对象将被复制到两个Survivor区域中的一个,我们假定是From区(两个区域实际上没有任何区别,From和To只是为了更好的说明工作流程),当From区域也被填满时,这个区域经过垃圾回收仍存活的对象将会被复制进入To区域,原From区域被清空,并且从Eden区过来的数据将直接进入To区域。当To区域也被填满时,之前从From区域过来的那部分数据如果仍在活动,则将被放入年老代。
需要注意的是,两个Survivor区域总有一个会是空的,并且Survivor是可以被设置为多个的。Survivor的个数越多,则对象在进入年老区之前要经历的垃圾回收次数也越多。
简单明了的说法:所有新生成的对象首先都是放在年轻代的。年轻代的目标就是尽可能快速的收集掉那些生命周期短的对象。年轻代分三个区。一个Eden区,两个Survivor区(一般而言)。大部分对象在Eden区中生成。当Eden区满时,还存活的对象将被复制到Survivor区(两个中的一个),当这个Survivor区满时,此区的存活对象将被复制到另外一个Survivor区,当这个Survivor去也满了的时候,从第一个Survivor区复制过来的并且此时还存活的对象,将被复制“年老区(Tenured)”。需要注意,Survivor的两个区是对称的,没先后关系,所以同一个区中可能同时存在从Eden复制过来对象,和从前一个Survivor复制过来的对象,而复制到年老区的只有从第一个Survivor去过来的对象。而且,Survivor区总有一个是空的。同时,根据程序需要,Survivor区是可以配置为多个的(多于两个),这样可以增加对象在年轻代中的存在时间,减少被放到年老代的可能。
年老代(old generation)
在年轻代中经历多次垃圾回收后仍旧存活的对象,都将进入年老代。这个区域中的对象生命周期较长,当这个区域也被写满时,会触发整个堆的垃圾回收。
堆的垃圾回收
堆的垃圾回收一般被分成两种,分别是Scavenge(minor) GC 和 Full GC。
Scavenge GC只发生在年轻代,当Eden区域的空间被写满时触发,触发后执行的动作就是发生在年轻代中的故事,不在复述。这种垃圾回收的目的就是尽快的为新生成的对象腾出空间,将生命周期较长的对象放入年老代。
Full GC 对整个堆进行整理,当年老代或者持久代被写满时或者java程序中system.gc()被调用时会触发。Full gc的执行会引起程序的短时间暂停,因此如何合理有效的分配堆空间,减少Full gc的次数是JVM优化的一个重要内容。
来自深入jvm体系结构书的解释:
什么情况下触发垃圾回收
由于对象进行了分代处理,因此垃圾回收区域、时间也不一样。GC有两种类型:Scavenge(minor) GC和Full GC。
Scavenge GC
一般情况下,当新对象生成,并且在Eden申请空间失败时,就会触发ScavengeGC,对Eden区域进行GC,清除非存活对象,并且把尚且存活的对象移动到Survivor区。然后整理Survivor的两个区。这种方式的GC是对年轻代的Eden区进行,不会影响到年老代。因为大部分对象都是从Eden区开始的,同时Eden区不会分配的很大,所以Eden区的GC会频繁进行。因而,一般在这里需要使用速度快、效率高的算法,使Eden去能尽快空闲出来。
Full GC
对整个堆进行整理,包括Young、Tenured和Perm。Full GC因为需要对整个对进行回收,所以比ScavengeGC要慢,因此应该尽可能减少FullGC的次数。在对JVM调优的过程中,很大一部分工作就是对于FullGC的调节。有如下原因可能导致Full GC:
·年老代(Tenured)被写满
·持久代(Perm)被写满
·System.gc()被显示调用
·上一次GC之后Heap的各域分配策略动态变化
- jvm中分代垃圾回收和触发垃圾回收
- JVM分代和垃圾回收
- JVM分代垃圾回收
- JVM分代垃圾回收
- JVM和垃圾回收
- JVM垃圾回收--年轻代、年老点和持久代
- JVM垃圾回收--年轻代、年老点和持久代
- JVM垃圾回收算法之新生代和老年代
- JVM垃圾回收算法之新生代和老年代
- jvm垃圾回收是什么时候触发的? 垃圾回收算法? 都有哪些垃圾回收器
- JVM调优:分代垃圾回收详述
- JVM调优(六):分代垃圾回收
- JVM垃圾分代回收算法详解
- jvm基础知识六---分代垃圾回收
- 漫谈 JVM 内存分代、垃圾回收
- JVM 内存分代、垃圾回收漫谈
- JVM 内存分代、垃圾回收漫谈
- JVM原理和垃圾回收
- ACM 搜索 hdu1240 Asteroids!
- 判断有向图是否有环
- java中包及修饰符的研究与应用
- 线段树
- JAVA字符串格式化-String.format()的使用总结
- jvm中分代垃圾回收和触发垃圾回收
- 拉低程序员社会地位的十大因素
- Move Zeroes
- java-反射初学(2)
- 深入理解JVM02--深入理解对象的创建、内存布局、访问定位
- word2vec (二) CBOW
- DFS
- IDEA在编辑时提示could not autowire
- php变量后加中括号