JVM详解-从入门到深入了解

Java Virtual Mechine

About JVM

  • 内存划分

|center

  • 堆内存分配

    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 主要存放应用程序中生命周期长的存活对象

About GC

对象存活
  • 引用计数 
    对象新增一个引用,那么计数增1.
  • 可达性分析 
    从GC roots 开始向下搜索,经历的链路成为引用链,没有被引用链关联的引用,为不可用对象。

Java中GC Roots:

  1. 虚拟机栈中引用的对象。
  2. 方法区中静态属性引用的对象。
  3. 方法区中常量引用的对象。
  4. 本地方法栈中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

    1. 空间整合,G1收集器采用标记整理算法,不会产生内存空间碎片。分配大对象时不会因为无法找到连续空间而提前触发下一次GC。

    2. 可预测停顿,这是G1的另一大优势,降低停顿时间是G1和CMS的共同关注点,但G1除了追求低停顿外,还能建立可预测的停顿时间模型,能让使用者明确指定在一个长度为N毫秒的时间片段内,消耗在垃圾收集上的时间不得超过N毫秒,这几乎已经是实时Java(RTSJ)的垃圾收集器的特征了。

内存分为多个大小相等的独立区域(Region) 

  • 收集步骤:

    1. 标记阶段,首先初始标记(Initial-Mark),这个阶段是停顿的(Stop the World Event),并且会触发一次普通Mintor GC。对应GC log:GC pause (young) (inital-mark)。
    2. Root Region Scanning,程序运行过程中会回收survivor区(存活到老年代),这一过程必须在young GC之前完成。
    3. Concurrent Marking,在整个堆中进行并发标记(和应用程序并发执行),此过程可能被young GC中断。在并发标记阶段,若发现区域对象中的所有对象都是垃圾,那个这个区域会被立即回收(图中打X)。同时,并发标记过程中,会计算每个区域的对象活性(区域中存活对象的比例)。 
    4. Remark, 再标记,会有短暂停顿(STW)。再标记阶段是用来收集 并发标记阶段 产生新的垃圾(并发阶段和应用程序一同运行);G1中采用了比CMS更快的初始快照算法:snapshot-at-the-beginning (SATB)。

    5. Copy/Clean up,多线程清除失活对象,会有STW。G1将回收区域的存活对象拷贝到新区域,清除Remember Sets,并发清空回收区域并把它返回到空闲区域链表中。

    6. 复制/清除过程后。回收区域的活性对象已经被集中回收到深蓝色和深绿色区域。

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行。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章