Java Virtual Mechine
About JVM
内存划分
堆内存分配
VM初始分配的内存由-Xms指定,默认是物理内存的1/64;JVM最大分配的内存由-Xmx指 定,默认是物理内存的1/4。默认空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制;空余堆内存大于70%时,JVM会减少堆直到 -Xms的最小限制。因此服务器一般设置-Xms、-Xmx相等以避免在每次GC 后调整堆的大小。对象的堆内存由称为垃圾回收器的自动内存管理系统回收。
组成 详解
Young Generation 即图中的Eden + Survivor (From Space + To Space)
Eden 存放新生的对象,也是主要对象存放位置
Survivor Space 有两个,存放每次垃圾回收后存活的对象,总会存在一个为空
Old Generation Tenured Generation 即图中的Old Space 主要存放应用程序中生命周期长的存活对象
对象存活
引用计数
对象新增一个引用,那么计数增1.
可达性分析
从GC roots 开始向下搜索,经历的链路成为引用链,没有被引用链关联的引用,为不可用对象。
Java中GC Roots:
虚拟机栈中引用的对象。
方法区中静态属性引用的对象。
方法区中常量引用的对象。
本地方法栈中JNI引用的对象。
GC 算法
Mark-Sweep 标记-清除
缺点: 效率较低;碎片化严重。
Copy 复制算法
缺点: 持续复制,效率低。
Mark-Compact 标记-压缩(老年代使用)
GC Collectors
Serial
有点古老,串行收集,在多cpu,多core的今天,已经渐渐被淘汰:
参数控制: -XX:+UseSerialGC
ParNew
Serial 的多线程版本,新生代并行,复制算法,老年代串行,标记-压缩算法。
参数控制: -XX:+UseParNewGC; -XX:ParallelGCThreads 线程数量。
Parallel Scavenge
类似ParNew,他关注的系统的吞吐量,也可以通过参数实现自适应性调节控制。新生代复制算法,老年代标记-压缩算法。
Parallel Old
since jdk 1.6
多线程 + 标记-整理算法
参数控制: -XX:+UseParallelOldGC
CMS Concurrent Mark Sweep
一种以最短停顿为目标的收集器
初始标记(initial mark) stop-the-world,标记gc roots 直接关联对象。
并发标记(concurrent mark)trace gc roots
重新标记(remark) stop-the-world
并发清除(concurrent sweep)
优点:并发收集,低停顿;
缺点:大量碎片;并发阶段;
参数控制: -XX:+UseConcMarkSweepGC,-XX:+ UseCMSCompactAtFullCollection 在Full GC后,进行一次碎片整理;整理过程是独占的,会引起停顿时间变长.
Garbage First
空间整合,G1收集器采用标记整理算法,不会产生内存空间碎片。分配大对象时不会因为无法找到连续空间而提前触发下一次GC。
可预测停顿,这是G1的另一大优势,降低停顿时间是G1和CMS的共同关注点,但G1除了追求低停顿外,还能建立可预测的停顿时间模型,能让使用者明确指定在一个长度为N毫秒的时间片段内,消耗在垃圾收集上的时间不得超过N毫秒,这几乎已经是实时Java(RTSJ)的垃圾收集器的特征了。
内存分为多个大小相等的独立区域(Region)
收集步骤:
标记阶段,首先初始标记(Initial-Mark),这个阶段是停顿的(Stop the World Event),并且会触发一次普通Mintor GC。对应GC log:GC pause (young) (inital-mark)。
Root Region Scanning,程序运行过程中会回收survivor区(存活到老年代),这一过程必须在young GC之前完成。
Concurrent Marking,在整个堆中进行并发标记(和应用程序并发执行),此过程可能被young GC中断。在并发标记阶段,若发现区域对象中的所有对象都是垃圾,那个这个区域会被立即回收(图中打X)。同时,并发标记过程中,会计算每个区域的对象活性(区域中存活对象的比例)。
Remark, 再标记,会有短暂停顿(STW)。再标记阶段是用来收集 并发标记阶段 产生新的垃圾(并发阶段和应用程序一同运行);G1中采用了比CMS更快的初始快照算法:snapshot-at-the-beginning (SATB)。
Copy/Clean up,多线程清除失活对象,会有STW。G1将回收区域的存活对象拷贝到新区域,清除Remember Sets,并发清空回收区域并把它返回到空闲区域链表中。
复制/清除过程后。回收区域的活性对象已经被集中回收到深蓝色和深绿色区域。
About Monitor
jstat
HotSpot JVM 提供的一个监控工具,不仅提供GC操作的信息,还有提供类装载操作的信息以及运行时便已操作对的信息。
使用方法 -> jstat -[option] [other-option] [interval] [times] ; 【jvmId】的获取 ps -ef | grep java
输入参数 option
参数 描述
gc 输出每个堆区域的当前可用空间以及已用空间(Eden,Survivor等等),GC执行的总次数,GC操作累计所花费的时间。
gccapacity 输出每个堆区域的最小空间限制(ms)/最大空间限制(mx),当前大小,每个区域之上执行GC的次数。(不输出当前已用空间以及GC执行时间)。
gccause 输出-gcutil提供的信息以及最后一次执行GC的发生原因和当前所执行的GC的发生原因
gcnew 输出Young的GC性能
gcnewcapacity Young空间大小的统计
gcold OLD 空间GC性能
gcoldcapacity OLD空间大小的统计
gcpermcapacity perm大小的统计
gcutil 输出每个堆区域使用占比,以及gc执行的总次数和GC操作所花费的时间
- 输出数据介绍 :
S0/S1/E/O/P [C/U] - 对应区域的空间大小和使用量,单位KB,
YGC/FGC[-/T] - GC的统计次数、时间
NGC/OGC/PGC[/MN/MX] 对应区域当前大小/最小值/最大值
GCC/LGCC 当前/最后一次GC的原因
TT 老年化阈值,在移动向老年代之前,能够在新生代存活次数。
MTT 最大老年化阈值,同上。
DSS 幸存者所需要的空间大小,单位KB
其中:
C - capacity 空间大小
U - used 使用量
T - 对应GC时间
other-option
-hn 展示每次输出数据的前n行。 -h3 只显示前3行。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。