Java Hotspot VM 系列文章
先介绍一些基本概念:
1> Minor GC、Major GC和Full GC
1.1 Minor GC
从年轻代空间(包括 Eden 和 Survivor 区域)回收内存被称为 Minor GC
Collecting garbage from Young space (consisting of Eden and Survivor spaces) is called a Minor GC
但是,当发生Minor GC事件的时候,一些有趣的地方需要注意到:
(1).当 JVM 无法为一个新的对象分配空间时会触发 Minor GC,比如当 Eden 区满了。所以分配内存的频率越高,越频繁执行 Minor GC
(2).内存池被填满的时候,其中的内容全部会被复制,指针会从0开始跟踪空闲内存。Eden 和 Survivor 区进行了标记和复制操作,
取代了经典的标记、扫描、压缩、清理操作。所以 Eden 和 Survivor 区不存在内存碎片。写指针总是停留在所使用内存池的顶部。
(3).执行 Minor GC 操作时,不会影响到永久代,从永久代到年轻代的引用被当成 GC roots,从年轻代到永久代的引用在标记阶段被直接忽略掉。
(4).质疑常规的认知,所有的 Minor GC 都会触发“全世界的暂停(stop-the-world)”,停止应用程序的线程。对于大部分应用程序,停顿导致的延迟都是可以忽略不计的。其中的真相就 是,大部分 Eden 区中的对象都能被认为是垃圾,永远也不会被复制到 Survivor 区或者老年代空间。如果正好相反,Eden 区大部分新生对象不符合 GC 条件,Minor GC 执行时暂停的时间将会长很多
1.2 Major GC
Major GC is cleaning the Tenured space
One should notice that there is no formal definitions present for those terms. Neither in JVM specification nor in the Garbage Collection research papers. But on the first glance, building these definitions on top of what we know to be true about Minor GC cleaning Young space should be simple:
大家应该注意到,目前,Major GC, Full GC这些术语无论是在 JVM 规范还是在垃圾收集研究论文中都没有正式的定义
很不幸,实际上有点复杂且令人困惑。首先,许多 Major GC 是由 Minor GC 触发的,所以很多情况下将这两种 GC 分离是不太可能的。另一方面,许多现代垃圾收集机制会清理部分永久代空间,所以使用“cleaning”一词只是部分正确
1.3 Full GC
Full GC is cleaning the entire Heap – both Young and Tenured spaces
我们不用去关心到底是叫 Major GC 还是 Full GC,大家应该关注当前的 GC 是否停止了所有应用程序的线程,还是能够并发的处理而不用停掉应用程序的线程
reference from February 25, 2015 by Nikita Salnikov-Tarnovski
https://plumbr.eu/blog/garbage-collection/minor-gc-vs-major-gc-vs-full-gc
2> jstat
jstat [-命令选项] [vmid] [间隔时间/毫秒] [查询次数]
vmid ==> Virtual Machine Identifier.
A vmid takes the following form: [@[:]]
Where is the local vm identifier for the target
Java virtual machine, typically a process id; is
the name of the host running the target Java virtual machine;
and is the port number for the rmiregistry on the
target host. See the jvmstat documentation for a more complete
description of the Virtual Machine Identifier.
Example:
root@client:~# jstat -class 9581 //类加载统计
Loaded Bytes Unloaded Bytes Time
7605 15296.7 32 52.1 6.13
root@client:~# jstat -compiler 9581 //编译统计
Compiled Failed Invalid Time FailedType FailedMethod
1666 1 0 32.72 1 java/lang/Class initAnnotationsIfNecessary
root@client:~# jstat -gccapacity 9581 //堆内存统计
NGCMN NGCMX NGC S0C S1C EC OGCMN OGCMX OGC OC PGCMN PGCMX PGC PC YGC FGC
87552.0 175104.0 175104.0 1024.0 1024.0 173056.0 175104.0 349184.0 211456.0 211456.0 131072.0 262144.0 131072.0 131072.0 498 4
root@client:~# jstat -gcnew 9581 //新生代垃圾回收统计
S0C S1C S0U S1U TT MTT DSS EC EU YGC YGCT
1024.0 1024.0 0.0 800.0 1 15 1024.0 173056.0 114737.8 509 5.064
root@client:~# jstat -gcnewcapacity 9581 //新生代内存统计
NGCMN NGCMX NGC S0CMX S0C S1CMX S1C ECMX EC YGC FGC
87552.0 175104.0 175104.0 58368.0 1024.0 58368.0 1024.0 174080.0 173056.0 520 4
root@client:~# jstat -gcold 9581 //老年代垃圾回收统计
PC PU OC OU YGC FGC FGCT GCT
131072.0 46468.0 211456.0 128841.0 531 4 1.645 6.894
root@client:~# jstat -gcoldcapacity 9581 //老年代内存统计
OGCMN OGCMX OGC OC YGC FGC FGCT GCT
175104.0 349184.0 211456.0 211456.0 536 4 1.645 6.935
root@client:~# jstat -gcutil 9581 //总结垃圾回收统计
S0 S1 E O P YGC YGCT FGC FGCT GCT
78.12 0.00 30.14 53.04 35.46 682 6.598 5 1.872 8.470
root@client:~# jstat -gcmetacapacity 9581 //元数据空间统计java>=8
root@client:~# jstat -printcompilation 9581 //JVM编译方法统计
Compiled Size Type Method
1680 196 1 org/apache/catalina/util/LifecycleSupport fireLifecycleEvent
请参考以下博文:
http://blog.csdn.net/maosijunzi/article/details/46049117
2.1> java < 8
java version "1.7.0_45"
Java(TM) SE Runtime Environment (build 1.7.0_45-b18)
Java HotSpot(TM) 64-Bit Server VM (build 24.45-b08, mixed mode)
root@client:~# jstat -gc -t 9581 1s
Timestamp S0C S1C S0U S1U EC EU OC OU PC PU YGC YGCT FGC FGCT GCT
80.6 4608.0 4608.0 768.0 0.0 164864.0 69445.5 208896.0 127906.6 131072.0 46478.5 66 1.351 1 0.526 1.877
81.6 4608.0 4608.0 768.0 0.0 164864.0 125913.2 208896.0 127906.6 131072.0 46479.0 66 1.351 1 0.526 1.877
82.6 4608.0 4608.0 768.0 0.0 164864.0 125913.2 208896.0 127906.6 131072.0 46479.0 66 1.351 1 0.526 1.877
83.6 4608.0 4608.0 768.0 0.0 164864.0 125913.3 208896.0 127906.6 131072.0 46479.0 66 1.351 1 0.526 1.877
84.6 4608.0 4608.0 768.0 0.0 164864.0 125913.3 208896.0 127906.6 131072.0 46479.0 66 1.351 1 0.526 1.877
85.6 4608.0 4608.0 768.0 0.0 164864.0 125913.3 208896.0 127906.6 131072.0 46479.0 66 1.351 1 0.526 1.877
86.6 4608.0 4608.0 768.0 0.0 164864.0 125913.4 208896.0 127906.6 131072.0 46479.0 66 1.351 1 0.526 1.877
jstat上面的指标进行介绍:
C 代表总量, U代表使用量。
S0、S1 代表的是幸存1区,幸存2区或者叫做from或者to区。
E 代表Eden,P代表老年代,
EC表示Eden的大小
EU表示Eden的使用
OC老年代的大小
OU老年代的使用的量
PC Permanent Space大小
PU Permanent Space 的使用量
YGC代表Minor GC次数,T代表时间,
YGCT代表Minor GC所耗时间
FGC代表Full GC
FGC代表Full GC所耗时间
GCT代表所有GC所耗时间
2.2> java >=8
java version "1.8.0_60"
Java(TM) SE Runtime Environment (build 1.8.0_60-b27)
Java HotSpot(TM) 64-Bit Server VM (build 25.60-b23, mixed mode)
root@client:~# jstat -gc -t 7656 1s
Timestamp S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
9103.1 512.0 512.0 0.0 192.0 173568.0 156306.7 175104.0 128993.9 57560.0 56323.8 6656.0 6314.9 4835 32.343 2 0.343 32.687
9104.2 512.0 512.0 0.0 192.0 173568.0 156306.7 175104.0 128993.9 57560.0 56323.8 6656.0 6314.9 4835 32.343 2 0.343 32.687
9105.2 512.0 512.0 0.0 192.0 173568.0 156306.7 175104.0 128993.9 57560.0 56323.8 6656.0 6314.9 4835 32.343 2 0.343 32.687
9106.2 512.0 512.0 0.0 192.0 173568.0 156306.7 175104.0 128993.9 57560.0 56323.8 6656.0 6314.9 4835 32.343 2 0.343 32.687
9107.2 512.0 512.0 0.0 192.0 173568.0 156306.7 175104.0 128993.9 57560.0 56323.8 6656.0 6314.9 4835 32.343 2 0.343 32.687
9108.2 512.0 512.0 0.0 192.0 173568.0 156393.3 175104.0 128993.9 57560.0 56323.8 6656.0 6314.9 4835 32.343 2 0.343 32.687
jstat上面的指标进行介绍:
C 代表总量, U代表使用量。
S0、S1 代表的是幸存1区,幸存2区或者叫做from或者to区。
E 代表Eden,P代表老年代,
EC表示Eden的大小
EU表示Eden的使用
OC老年代的大小
OU老年代的使用的量
MC 方法区大小
MU 方法区的使用量
CCSC 压缩类空间大小
CCSU 压缩类空间使用量
YGC代表Minor GC次数,T代表时间,
YGCT代表Minor GC所耗时间
FGC代表Full GC
FGC代表Full GC所耗时间
GCT代表垃圾回收消耗总时间