grafana面板介绍:
https://grafana.com/grafana/dashboards/4701-jvm-micrometer/?spm=a2c4g.11186623.0.0.6f4c1640jJ0xzj
Quick Facts(概览)
- Uptime:进程启动时长
- Start Time:启动时间
- Heap used:堆内存使用率
Java 虚拟机具有一个堆(Heap),堆是运行时数据区域,所有类实例和数组的内存均从此处分配。堆是在 Java 虚拟机启动时创建的。
对象的堆内存由称为垃圾回收器的自动内存管理系统回收。堆的大小可以固定,也可以扩大和缩小。堆的内存不需要是连续空间。
在JVM中堆之外的内存称为非堆内存(Non-heap memory)
Java 虚拟机具有一个由所有线程共享的方法区。方法区属于非堆内存。它存储每个类结构,如运行时常数池、字段和方法数据,以及方法和构造方法的代码。它是在 Java 虚拟机启动时创建的。
方法区在逻辑上属于堆,但 Java 虚拟机实现可以选择不对其进行回收或压缩。与堆类似,方法区的大小可以固定,也可以扩大和缩小。方法区的内存不需要是连续空间。
除了方法区外,Java 虚拟机实现可能需要用于内部处理或优化的内存,这种内存也是非堆内存。例如,JIT 编译器需要内存来存储从 Java 虚拟机代码转换而来的本机代码,从而获得高性能。
堆和非堆内存有以下几个概念
init
表示JVM在启动时从操作系统申请内存管理的初始内存大小(以字节为单位)。JVM可能从操作系统请求额外的内存,也可以随着时间的推移向操作系统释放内存(经实际测试,这个内存并没有过主动释放)。这个init的值可能不会定义。
used
表示当前使用的内存量(以字节为单位)
committed
表示保证可供 Jvm使用的内存大小(以字节为单位)。 已提交内存的大小可能随时间而变化(增加或减少)。 JVM也可能向系统释放内存,导致已提交的内存可能小于 init,但是committed永远会大于等于used。
max
表示可用于内存管理的最大内存(以字节为单位)。
I/O Overview(服务黄金指标)
- Rate:
ops/s Operation per second 每秒的操作数
QPS (Queries Per Second意思是“每秒查询率”) - Errors:错误数
- Duration:请求耗时
- Utilisation:饱和度
JVM Memory(JVM内存)
init:表示JVM在启动时从操作系统申请内存管理的初始内存大小(以字节为单位)。JVM可能从操作系统请求额外的内存,也可以随着时间的推移向操作系统释放内存(经实际测试,这个内存并没有过主动释放)。这个init的值可能不会定义。
used:表示当前使用的内存量
committed:表示保证可供 Jvm使用的内存大小。 已提交内存的大小可能随时间而变化(增加或减少)。 JVM也可能向系统释放内存,导致已提交的内存可能小于 init,但是committed永远会大于等于used。
max:表示可用于内存管理的最大内存
JVM Misc(JVM负载)
- CPU usage:CPU使用率
- Load:核心数
- Threads:线程数
- Thread Status:各状态线程数
- Log Events:LogBack日志数
- File Descriptors:文件描述符
JVM Memory Pools(Heap)(JVM堆内存详情)
- G1 Eden Space:伊甸区,对象被创建的时候首先放到这个区域,进行垃圾回收后,不能被回收的对象被放入到空的survivor区域。
- G1 Old Gen:老年代,用于存放新生代中经过多次垃圾回收仍然存活的对象,也有可能是新生代分配不了内存的大对象会直接进入老年代。经过多次垃圾回收都没有被回收的对象,这些对象的年代已经足够old了,就会放入到老年代。
- G1 Survivor Space:幸存者区,用于保存在eden space内存区域中经过垃圾回收后没有被回收的对象。Survivor有两个,分别为To Survivor、 From Survivor,这个两个区域的空间大小是一样的。执行垃圾回收的时候Eden区域不能被回收的对象被放入到空的survivor(也就是To Survivor,同时Eden区域的内存会在垃圾回收的过程中全部释放),另一个survivor(即From Survivor)里不能被回收的对象也会被放入这个survivor(即To Survivor),然后To Survivor 和 From Survivor的标记会互换,始终保证一个survivor是空的。
JVM Memory Pools(Non-Heap)(JVM非堆内存详情)
- Metaspace:Java8,永久代被干掉了,有了“metaspace”的概念,存储jvm中的元数据,包括byte code,class等信息。
- Compressed Class Space:Java8在UseCompressedOops之外,额外增加了一个新选项叫做UseCompressedClassPointer。这个选项打开后,class信息中的指针也用32bit的Compressed版本。而这些指针指向的空间被称作“Compressed Class Space”。默认大小是1G,但可以通过“CompressedClassSpaceSize”调整。如果你的java程序引用了太多的包,有可能会造成这个空间不够用
- CodeHeap ‘profiled nmethods’
- CodeHeap ‘non-profiled nmethods’
- CodeHeap ‘non-nmethods’
Garbage Collection(垃圾回收)
- Collections:GC次数
Major GC通常是跟full GC是等价的,收集整个GC堆。
Full GC:收集整个堆,包括young gen、old gen、perm gen(如果存在的话,java8的时候去除PermGen,将其中的方法区移到non-heap中的Metaspace)等所有部分的模式。
Metadata GC Threshold:导致Full GC的一种原因
Allocation Failure:导致Minor GC的一种原因,比如在年轻代中没有足够的空间能够存储新的数据了会触发(Minor GC 它不表示只GC新生代,并且现有的不管是新生代还是老年代都会STW。STW:在执行垃圾收集算法时,Java应用程序的其他所有线程都被挂起(除了垃圾收集帮助器之外),Java中一种全局暂停现象,全局停顿,所有Java代码停止,native代码可以执行,但不能与JVM交互;这些现象多半是由于gc引起。) - Pause Durations:GC暂停时间
- Allocated/Promoted:内存分配/晋升,
Allocated:分配的内存量,分配速率过高就会严重影响程序的性能。在JVM中会导致巨大的GC开销。计算 上一次垃圾收集之后,与下一次GC开始之前的年轻代使用量, 两者的差值除以时间,就是分配速率
Promoted:提升速率, 用于衡量单位时间内从年轻代提升到老年代的数据量
ClassLoading(类加载)
- Classes loaded:已加载类数量
- Class delta:加载类数量变化
Buffer Pools
Direct Buffers:这是一块在Java堆外分配的,可以在Java程序中访问的内存。NIO中相对有些特殊的东西,在NIO中有一个可以直接访问物理内存的Buffer叫做Direct Buffer。普通Buffer分配的是JVM的堆内存,而Direct Buffer是直接分配物理内存,堆外内存。DirectBuffer当然还有一个直观的优点,不被GC管理,所以发生GC的时候,整理内存的压力就会小。当然,我后面也会讲,它并不是完全不被GC管理,它还是能被回收的
Mapped Buffers
获取机器配置
对于堆的初始值和最大值,可以使用如下命令查看
在Windows里:
java -XX:+PrintFlagsFinal -version | findstr /i “HeapSize PermSize ThreadStackSize”
在Linux里:
java -XX:+PrintFlagsFinal -version | grep -iE ‘HeapSize|PermSize|ThreadStackSize’