深入理解java虚拟机 java虚拟机有什么用( 四 )


4.5.垃圾收集器

  • Serial收集器: 这个收集器是一个单线程的收集器,但它的单线程的意义不仅仅说明它会只使用一个COU或一条收集线程去完成垃圾收集工作,更重要的是它在进行垃圾收集时,必须暂停其他所有的工作线程,直到它手机结束
  • ParNew 收集器:Serial收集器的多线程版本,除了使用了多线程进行收集之外,其余行为和Serial收集器一样
并行:指多条垃圾收集线程并行工作,但此时用户线程仍然处于等待状态
并发:指用户线程与垃圾收集线程同时执行(不一定是并行的,可能会交替执行),用户程序在继续执行,而垃圾收集程序运行于另一个CPU上
  • Parallel Scavenge
收集器是一个新生代收集器,它是使用复制算法的收集器,又是并行的多线程收集器 。
吞吐量:就是CPU用于运行用户代码的时间与CPU总消耗时间的比值 。即吞吐量=运行用户代码时间/(运行用户代码时间+垃圾收集时间)
  • Serial Old 收集器:
是Serial收集器的老年代版本,是一个单线程收集器,使用标记整理算法
  • Parallel Old 收集器:
Parallel Old是Paraller Seavenge收集器的老年代版本,使用多线程和标记整理算法
  • CMS收集器:
CMS收集器是基于标记清除算法实现的,整个过程分为4个步骤:
1. 初始标记
2. 并发标记
3. 重新标记
4. 并发清除
优点:并发收集、低停顿
缺点:
1. CMS收集器对CPU资源非常敏感,CMS默认启动的回收线程数是(CPU数量+3)/4,
2. CMS收集器无法处理浮动垃圾,可能出现Failure失败而导致一次Full G场地产生
3. CMS是基于标记清除算法实现的
  • G1收集器:
它是一款面向服务器应用的垃圾收集器
1. 并行与并发:利用多CPU缩短STOP-The-World停顿的时间
2. 分代收集
3. 空间整合:不会产生内存碎片
4. 可预测的停顿
运作方式:初始标记,并发标记,最终标记,筛选回收
4.6. 内存分配与回收策略
4.6.1 对象优先在Eden分配:
大多数情况对象在新生代Eden区分配,当Eden区没有足够空间进行分配时,虚拟机将发起一次Minor GC
4.6.2 大对象直接进入老年代:
所谓大对象就是指需要大量连续内存空间的Java对象,最典型的大对象就是那种很长的字符串以及数组 。这样做的目的是避免Eden区及两个Servivor之间发生大量的内存复制
4.6.3长期存活的对象将进入老年代
如果对象在Eden区出生并且尽力过一次MinorGC后仍然存活,并且能够被Servivor容纳,将被移动到Servivor空间中,并且把对象年龄设置成为1.对象在Servivor区中每熬过一次MinorGC,年龄就增加1岁,当它的年龄增加到一定程度(默认15岁),就将会被晋级到老年代中
4.6.4动态对象年龄判定
为了更好地适应不同程序的内存状况,虚拟机并不是永远地要求对象的年龄必须达到了MaxTenuringThreshold才能晋级到老年代,如果在Servivor空间中相同年龄所有对象的大小总和大于Survivor空间的一半,年龄大于或等于该年龄的对象就可以直接进入到老年代,无须登到MaxTenuringThreshold中要求的年龄
4.6.5 空间分配担保:
在发生Minor GC之前,虚拟机会检查老年代最大可用的连续空间是否大于新生代所有对象总空间,如果这个条件成立,那么MinorDC可以确保是安全的 。如果不成立,则虚拟机会查看HandlePromotionFailure设置值是否允许担保失败 。如果允许那么会继续检查老年代最大可用的连续空间是否大于晋级到老年代对象的平均大小,如果大于,将尝试进行一次MinorGC,尽管这次MinorGC是有风险的:如果小于,或者HandlePromotionFailure设置不允许冒险,那这时也要改为进行一次Full GC
五、虚拟机类加载机制
虚拟机吧描述类的数据从Class文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制
在Java语言里面,类型的加载 。连接和初始化过程都是在程序运行期间完成的
5.1 类加载的时机
类被加载到虚拟机内存中开始,到卸载为止,整个生命周期包括:加载、验证、准备、解析、初始化、使用和卸载7个阶段
加载、验证、准备、初始化和卸载这5个阶段的顺序是确定的,类的加载过程必须按照这种顺序按部就班地开始,而解析阶段则不一定:它在某些情况下可以再初始化阶段之后再开始,这个是为了支持Java语言运行时绑定(也成为动态绑定或晚期绑定)