Hotspot关键组件
Java虚拟机的主要组件,包括类加载器、运行时数据区和执行引擎。 Java虚拟机有关性能的关键组件已经在下面的图片上高亮显示了。
Java虚拟机有三个组件关注着什么时候进行性能优化,堆空间是你的对象所存储的地方,这个区域
被启动时选择的垃圾回收器管理,大部分调优选项与调整堆大小和根据你的情况选择最适当的垃圾收集器相关。即时编译器对性能也有很大的影响,但是使用新版本的Java虚拟机时很少需要调整。
性能基础
典型的,当调优一个Java应用时,把焦点放在两个主要的目标上:响应能力或者吞吐量。随着教程的进行我们会再重新提及这些概念。
响应能力指的是一个应用回应一个请求数据的速度有多快。响应能力高那么只能频繁地执行内存回收,但这又引起了年轻代内存的缩减和导致程序吞吐量的下降 ,响应能力优先,就意味着尽可能的让单次stw的时间最短,示例包括:
- 桌面UI响应事件的速度
- 网站返回网页的速度
- 数据查询返回的速度
- 对关注响应能力的应用来说,长暂停时间是不可接受的,重点是在短的时间周期内能做出响应。
吞吐量就是cpu用于运行用户代码时间与cpu总消耗时间比值,即吞吐量 = 运行用户代码时间/(运行用户代码时间+垃圾收集时间),吞吐量高必然需要降低内存回收频率,但是这样就会导致gc需要更长的暂停时间来执行内存回收。举例如何衡量吞吐量,包括:
- 给定时间内完成事务的数量
- 一小时内批处理程序完成的工作数量
- 一小时内数据查询完成的数量
- 比如:虚拟机总共运行100分钟,其中垃圾收集器花掉1分钟,那么吞吐量就是99%。
对关注吞吐量的应用来说长暂停时间是可以接受的。由于高吞吐量的应用关注的基准在更长周期时间上,所以快速响应时间不在考虑之内。
G1垃圾收集器计划长期替换并发标记清除收集器(CMS,Concurrent Mark-Sweep Collector)。G1和CMS比较,有一些不同点让G1成为一个更好的解决方案。一个不同点是G1是一个压缩收集器。G1收集器充分地压缩空间以完全避免为分配空间使用细粒度的空闲列表,而不是依赖于区块。这相当简化了收集器的部件,和尽量消除可能的碎片问题。同时,G1收集器相比CMS收集器而方言,提供更可预言的垃圾收集暂停时间,允许用户指定想要暂停时间指标。
G1垃圾收集器
- g1垃圾收集器是一个面向服务端的垃圾收集器,适用于多核处理器、大内存容量的服务端系统。
- 它满足短时间gc停顿的同时达到一个较高的吞吐量
- JDK7以上版本适用
G1收集器的设计目标
- 与应用线程同时工作,几乎不需要stop the world
- 整理剩余空间,不产生内存碎片(CMS 只能在Full GC时,用stop the world整理内存碎片)
- GC停顿更加可控
- 不牺牲系统的吞吐量
- GC不要求额外的内存空间(CMS需要预留空间存储浮动垃圾)‘
- G1在某些方面弥补了CMS的不足,比如,CMS使用的是mark-sweep算法,自然会产生内存碎片;然而G1基于copying算法,高效的整理剩余内存,而不需要管理内存碎片。
- 另外,G1提供了更多手段,以达到对gc停顿时间的可控
G1收集器堆结构
- heap被划分一个个相等的不连续的内存区域(regions),每个region都有一个分代角色:eden、survivor、old
- 对每个角色的数量并没有强制的限定,也就是说对每种分代内存的大小,可以动态变化
- G1最大特点就是高效的执行回收,优先去执行那些大量对象可回收的区域(region)
- G1使用了gc停顿可预测的模型,来满足用户设定的gc停顿时间,根据用户设定的目标时间,G1会自动地选择那些region要清除,一次清除多少个region。
- G1从多个region中复制存活的对象,然后集中放入一个region中,同时整理、清除内存(copying收集算法)
G1 vs CMS
- 对比使用mark-sweep的CMS,G1使用的copying算法不会造成内存碎片;
- 对比Parallel Scavenge(基于copying)、Parallel Old收集器(基于mark-compact-sweep),Parallel会对整个区域做整个区域做整理导致gc停顿会比较长,而g1只是特定地整理几个region。
- G1并非一个实时的收集器,与parallel Scavenge一样,对gc停顿时间的设置并不绝对生效,只是g1有较高的几率保证不超过设定的gc停顿时间。与之前的gc收集器对比,g1会根据用户设定的gc停顿时间,智能评估哪几个region需要被回收可以满足用户的设定
G1重要概念
- 分区(region):g1采用了不同的策略来解决并行、串行和cms收集器的碎片、暂停时间不可控等问题---G1将整个堆分成相同大小的分区
- 每个分区都可能是年轻代有可能是老年代,但是在同一时刻只能某个代。年轻代、幸存区、老年代这些概念还存在,成为逻辑上的概念,这样方便复用之前分代框架的逻辑
- 在物理上不需要连续,则带来了额外的好处----有的分区内垃圾对象特别多,有的分区内垃圾对象很少,G1会优先回收垃圾对象特别多的分区,这样可以花费较少的时间来回收这些分区的垃圾,这也是G1名字的由来,即首先收集垃圾最多的分区。
- 依然是在新生代满了的时候,对整个新生代进行回收---整个新生代的对象,要么被回收、要么晋升,至于新生代也采取分区机制的原因,则是因为这样跟老年代的策略统一,方便调整代的大小。
- G1还是一种带压缩的收集器,在回收老年代的分区时,是将存活的对象从一个分区拷贝到另一个可用分区,这个拷贝的过程就实现了局部的压缩。
- 收集集合(CSet): 一组可被回收的分区的集合。在CSet中存活的数据会在GC过程中被移动到另一个可用分区ÿ